agent-device 0.20.4 → 0.20.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.4.apk → agent-device-android-ime-helper-0.20.6.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.6.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.4.manifest.json → agent-device-android-ime-helper-0.20.6.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.4.apk → agent-device-android-snapshot-helper-0.20.6.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.6.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.4.manifest.json → agent-device-android-snapshot-helper-0.20.6.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +28 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +1 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +41 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +298 -92
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +126 -187
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.h +32 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.m +212 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +118 -8
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +134 -27
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +23 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +10 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -67
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +11 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +2 -22
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +48 -11
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -20
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +177 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +105 -448
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +587 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +18 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerXCTestEventBridge.h +72 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerXCTestEventBridge.m +89 -0
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android.js +1 -1
- package/dist/src/app-log-request-scope.js +1 -1
- package/dist/src/app-resolution.js +1 -1
- package/dist/src/apps.js +5 -5
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +34 -24
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +15 -15
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/context.js +1 -1
- package/dist/src/debug-symbols.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -0
- package/dist/src/generic.js +1 -1
- package/dist/src/ime-lifecycle.js +3 -3
- package/dist/src/index.d.ts +27 -7
- package/dist/src/input-actions.js +4 -4
- package/dist/src/interaction-runtime.js +1 -0
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction-touch-reference-frame.js +1 -0
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -2
- package/dist/src/interactor2.js +1 -1
- package/dist/src/internal/bin.js +2 -2
- package/dist/src/internal/daemon.js +15 -15
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +23 -2
- package/dist/src/linux.js +1 -1
- package/dist/src/process-exit.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +25 -24
- package/dist/src/remote-config.js +1 -1
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/reporting.js +2 -2
- package/dist/src/runner-client.js +1 -1
- 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/screenshot-geometry.js +1 -1
- package/dist/src/screenshot-result.js +4 -4
- package/dist/src/sdk-android-adb.d.ts +20 -2
- package/dist/src/sdk-android-adb.js +1 -1
- package/dist/src/sdk-batch-runner.js +3 -3
- package/dist/src/sdk-contracts.d.ts +17 -2
- package/dist/src/sdk-finders.d.ts +4 -20
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/{interaction.d.ts → sdk-selectors.d.ts} +98 -3
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selector-vocabulary.js +1 -1
- package/dist/src/selectors.d.ts +1 -46
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +3 -3
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +9 -8
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/text-surface.js +1 -0
- package/dist/src/viewport-dimension.js +13 -12
- package/dist/src/web.js +1 -1
- package/package.json +42 -34
- package/server.json +3 -3
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.4.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.4.apk.sha256 +0 -1
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -225
package/dist/src/registry.js
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import{_ as e,n as t,t as n}from"./sdk-contracts.js";import{$t as r,At as i,Dt as a,Et as o,Ht as s,It as c,Ot as ee,Pt as te,Qt as ne,St as re,Tt as ie,Vt as ae,Xt as oe,Yt as se,Zt as ce,_t as le,a as ue,bn as de,bt as fe,cn as pe,dn as me,en as he,jt as ge,n as _e,nn as ve,o as ye,r as be,st as xe,t as Se,tn as Ce,vn as we,vt as Te,wt as Ee,xn as De,xt as Oe,yn as ke,yt as Ae,zt as je}from"./viewport-dimension.js";import{A as Me,E as Ne,F as Pe,I as Fe,J as Ie,L as Le,M as Re,N as ze,P as Be,T as Ve,W as He,Y as Ue,_ as We,d as Ge,f as Ke,j as qe,o as Je,p as Ye,r as Xe,v as Ze}from"./screenshot-geometry.js";import{A as Qe,O as $e,U as et,W as tt,_ as nt,d as rt,f as it,h as at,i as ot,it as st,m as ct,p as lt,q as l,r as ut,u as dt,v as ft}from"./sdk-batch-runner.js";import{n as pt,t as mt}from"./sdk-device.js";import{a as ht}from"./sdk-remote-config.js";import{$ as gt,D as _t,T as vt,b as yt,x as bt,y as xt}from"./sdk-selectors.js";import{a as St,d as Ct,t as wt,u as Tt}from"./device.js";const Et=[{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:c,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:`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)`}],Dt=[{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:ht,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`}],Ot=[{key:`platform`,names:[`--platform`],type:`enum`,enumValues:pt,usageLabel:`--platform ${pt.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:te,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`,...re],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`}],kt=[{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:`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`},...ke,{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)`}],At=[...Dt,...Ot,...Et,...kt],jt=new Map;for(let e of At)for(let t of e.names)jt.set(t,e);function Mt(e){return jt.get(e)}function Nt(){return At}const Pt=new Set(Nt().map(e=>e.key));function Ft(e){let t=pe(e);return st({stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,...me(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,snapshotForceFull:e.forceFull,...de(e),appsFilter:e.appsFilter,kind:e.kind,out:e.out,count:e.count,fps:e.fps,screenshotMaxSize:e.maxSize,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 It(e,t){return{...Ft(e),...t}}function Lt(e,t){let n=e.inputSchema.properties;if(!n)return{};let r={},i=t;for(let e of Object.keys(n)){if(!Pt.has(e))continue;let t=i[e];Rt(t)&&(r[e]=t)}return r}function Rt(e){return typeof e==`boolean`||typeof e==`number`||typeof e==`string`}const zt=[`ref`,`selector`,`point`];function Bt(e,t=[]){return{type:`object`,properties:{...Tn(),...e},...t.length>0?{required:t}:{},additionalProperties:!1}}function Vt(e){return{type:`object`,description:e,properties:{x:{type:`number`},y:{type:`number`}},required:[`x`,`y`],additionalProperties:!1}}function Ht(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function u(e){return{type:`string`,...e?{description:e}:{}}}function Ut(e){return{type:`number`,...e?{description:e}:{}}}function Wt(e){return{type:`integer`,...e?{description:e}:{}}}function Gt(e){return{type:`boolean`,...e?{description:e}:{}}}function Kt(e){return{type:`array`,items:{type:`string`},...e?{description:e}:{}}}function qt(e){return{type:`object`,additionalProperties:!0,...e?{description:e}:{}}}function d(e){return{...e,required:!0}}function f(e){return C(u(e),b)}function p(e){return C(Ut(e),dn)}function m(e,t={}){return C(bn(e,t),(e,n)=>dt(e,n,t))}function h(e){return C(Gt(e),fn)}function g(e,t){return C(Ht(e,t),(t,n)=>mn(t,n,e))}function Jt(e){return C(qt(e),Cn)}function Yt(e){return C(Kt(e),wn)}function _(e){return C(e,(e,t)=>e[t])}function Xt(e,t){return C(e,t)}function Zt(){return C(En(),(e,t)=>e[t]===void 0?void 0:on(e,t))}function Qt(){return C(Dn(),(e,t)=>e[t]===void 0?void 0:sn(e,t))}function $t(e){return C(Vt(e),(e,t)=>e[t]===void 0?void 0:cn(e,t))}function v(){return{depth:m(`Snapshot traversal depth.`,{min:0}),scope:f(`Snapshot scope selector used before resolution.`),raw:h(`Use raw snapshot data during selector resolution.`)}}function en(){return{count:m(`Number of press/click repetitions.`,{min:1}),intervalMs:m(`Delay between repeated press/click actions.`,{min:0}),holdMs:m(`Hold duration for each action.`,{min:0}),jitterPx:m(`Randomization radius in pixels.`,{min:0}),doubleTap:h(`Request a double-tap action.`)}}function y(e){return Bt(xn(e),Sn(e))}function tn(t,n){let r=nn(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=rn(r,{readTargetAlias:!Object.hasOwn(n,`target`)});return S({...a,...x(a),...i})}function nn(t){if(t==null)return{};if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected object arguments.`);return t}function rn(e,t={}){return{session:b(e,`session`),platform:mn(e,`platform`,pt),deviceTarget:an(e,t),device:b(e,`device`),udid:b(e,`udid`),serial:b(e,`serial`),iosSimulatorDeviceSet:b(e,`iosSimulatorDeviceSet`),iosXctestrunFile:b(e,`iosXctestrunFile`),iosXctestDerivedDataPath:b(e,`iosXctestDerivedDataPath`),iosXctestEnvDir:b(e,`iosXctestEnvDir`),androidDeviceAllowlist:b(e,`androidDeviceAllowlist`),noRecord:fn(e,`noRecord`),daemonBaseUrl:b(e,`daemonBaseUrl`),daemonAuthToken:b(e,`daemonAuthToken`),tenant:b(e,`tenant`),runId:b(e,`runId`),leaseId:b(e,`leaseId`),cwd:b(e,`cwd`),debug:fn(e,`debug`)}}function an(t,n){let r=mn(t,`deviceTarget`,mt);if(n.readTargetAlias===!1||t.target===void 0)return r;let i=mn(t,`target`,mt);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 on(e,t){let n=kn(e,t),r=pn(n,`kind`,zt);switch(r){case`ref`:return{kind:r,ref:ln(n,`ref`),label:b(n,`label`)};case`selector`:return{kind:r,selector:ln(n,`selector`)};case`point`:return{kind:r,x:un(n,`x`),y:un(n,`y`)}}}function sn(e,t){let n=kn(e,t),r=pn(n,`kind`,[`ref`,`selector`]);return r===`ref`?{kind:r,ref:ln(n,`ref`),label:b(n,`label`)}:{kind:r,selector:ln(n,`selector`)}}function cn(e,t){let n=kn(e,t);return{x:un(n,`x`),y:un(n,`y`)}}function ln(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 b(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 un(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 dn(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`number`||!Number.isFinite(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be a finite number.`);return r}}function fn(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 pn(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 mn(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 x(e){return S({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 hn(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 gn(e){switch(e.kind){case`ref`:return{ref:e.ref,label:e.label};case`selector`:return{selector:e.selector}}}function _n(e){return{count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap}}function vn(e){return{depth:e.depth,scope:e.scope,raw:e.raw}}function yn(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 S(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function C(e,t){return{schema:e,required:!1,read:t}}function bn(e,t){return{...Wt(e),...t.min===void 0?{}:{minimum:t.min},...t.max===void 0?{}:{maximum:t.max}}}function xn(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,t.schema]))}function Sn(e){return Object.entries(e).flatMap(([e,t])=>t.required?[e]:[])}function Cn(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 wn(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 Tn(){return{session:{type:`string`,description:`Agent-device session name.`},platform:{type:`string`,enum:pt,description:`Platform selector used to resolve a device.`},deviceTarget:{type:`string`,enum:mt,description:`Device target form. Maps to the CLI --target flag.`},target:{type:`string`,enum:mt,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 En(){return{oneOf:[...On(),{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 Dn(){return{oneOf:On(),description:`UI element target by snapshot ref or selector expression.`}}function On(){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 kn(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 w(e,t){return n=>T(e,t?t(n):[],n)}function T(e,t,n,r){return{command:e,positionals:t,...r?{input:r}:{},options:An(n)}}function An(e){let t=jn(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 jn(e){return e===`mobile`||e===`tv`||e===`desktop`?e:void 0}function E(e){return S({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 Mn(e){return S({record:e.record})}function Nn(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 Pn(e){return S({depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw})}function Fn(e){return{depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw}}function In(e){return S({settle:e.settle,settleQuietMs:e.settleQuietMs,timeoutMs:e.timeoutMs})}function Ln(e){return S({count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap})}function Rn(e){if(`ref`in e&&e.ref!==void 0)return S({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=Vn(t);if(typeof n.ref==`string`)return[n.ref,...Un(n.label)];if(typeof n.selector==`string`)return[n.selector];if(n.kind===`point`||n.x!==void 0||n.y!==void 0)return[String(Hn(n.x,`x`)),String(Hn(n.y,`y`))];throw new e(`INVALID_ARGS`,`interaction requires @ref, selector, or point target`)}function Bn(t){let n=Vn(t);if(typeof n.ref==`string`)return[n.ref,...Un(n.label)];if(typeof n.selector==`string`)return[n.selector];throw new e(`INVALID_ARGS`,`element command requires @ref or selector target`)}function Vn(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 Hn(t,n){if(typeof t!=`number`||!Number.isFinite(t))throw new e(`INVALID_ARGS`,`point target requires numeric ${n}.`);return t}function Un(e){return typeof e==`string`&&e.length>0?[e]:[]}function Wn(t){let n=yt(t);if(!n.ok)throw new e(n.code,n.message);return`ref`in n?{ref:n.ref,label:Jn(t.slice(1))}:{selector:n.selector}}function Gn(t){let n=bt(t);if(!n.ok)throw new e(n.code,n.message);return n.format}function Kn(t,n={}){let r=et(t,n);if(!r)throw new e(`INVALID_ARGS`,xt);return r}function qn(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 Jn(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 Yn(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}function Xn(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 P(e){return e}function F(e){let t={},n={},r={},i={},a={};for(let o of e.commands){o.cliSchema&&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 Zn(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:ve(e)}}function Qn(e){let t=[`Batch completed: ${e.executed}/${e.total} steps in ${e.totalDurationMs}ms`];for(let n of e.results)t.push(er(n));return{data:e,text:t.join(`
|
|
2
|
-
`)}}const $n={batch:z(Qn)};function er(e){let t=ve(e.data)??e.command;return`${e.step}. OK ${t} (${e.durationMs}ms)`}function tr(e=ut){let t=nr(e);return L({name:`batch`,description:`Run multiple structured command steps in one daemon request.`,inputSchema:y(t),readInput:e=>ir(e,t)})}function nr(e){return{steps:d(Xt({type:`array`,description:`Structured batch steps. Each step uses a command name and the same input object as that command tool.`,items:rr(e)},(t,n)=>ar(t[n],e))),onError:g([`stop`],`Batch failure policy.`),maxSteps:m(`Maximum number of steps accepted for this batch.`,{min:1,max:1e3}),out:f(`Optional output path for command artifacts.`)}}function rr(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 ir(t,n){let r=tn(t,n),i=r.maxSteps??100;if(!it(i))throw new e(`INVALID_ARGS`,`Invalid batch maxSteps: ${String(r.maxSteps)}`);return rt(r.steps.length,i),{...r}}function ar(t,n){if(!Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected steps to be an array.`);return t.map((e,t)=>or(e,t+1,n))}function or(e,t,n){let r=at(e,t);return yn(r,[`command`,`input`,`runtime`],`Batch step ${t}`),{command:sr(r,t,n),input:ct(r,t),...cr(r,t)}}function sr(t,n,r){if(r===ut)return ot(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 cr(e,t){let n=lt(e.runtime,t);return n===void 0?{}:{runtime:n}}function lr(e){return t=>T(s.batch,[],{...t,batchSteps:ur(t.steps,e),batchOnError:t.onError,batchMaxSteps:t.maxSteps})}function ur(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)=>dr(e,t+1,n))}function dr(e,t,n){let r=at(e,t),i=fr(r,t),a=ct(r,t),o=lt(r.runtime,t),s=n(i,a,t);return{command:s.command,positionals:s.positionals,...s.input?{input:s.input}:{},flags:It(s.options,s.metadataFlags),runtime:o??s.options.runtime}}function fr(e,t){return ot(e.command,t)}const pr=tr(),mr=F({name:`batch`,clientSurface:!1,commands:[P({name:`batch`,metadata:pr,definition:R(pr,(e,t)=>e.batch.run(hr(t))),cliSchema:{usageOverride:`batch [--steps <json> | --steps-file <path>]`,listUsageOverride:`batch --steps <json> | --steps-file <path>`,helpDescription:`Execute multiple commands in one daemon request`,summary:`Run multiple commands`,allowedFlags:[`steps`,`stepsFile`,`batchOnError`,`batchMaxSteps`,`out`]},cliReader:(e,t)=>({...E(t),steps:t.batchSteps??[],onError:t.batchOnError,maxSteps:t.batchMaxSteps,out:t.out}),cliOutputFormatter:$n.batch})]});function hr(e){return{...x(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:y(n),readInput:e=>tn(e,n)})}const gr=`alert`,_r=H(gr,`Inspect or handle platform alerts.`,{action:g(Ue),timeoutMs:m()}),vr=P({name:gr,metadata:_r,definition:R(_r,(e,t)=>e.command.alert(t)),cliSchema:{usageOverride:`alert [get|accept|dismiss|wait] [timeout]`,positionalArgs:[`action?`,`timeout?`]},cliReader:(e,t)=>({...E(t),...br(e)}),daemonWriter:w(s.alert,e=>yr(e)),cliOutputFormatter:B});function yr(e){return[e.action??`get`,...j(e.timeoutMs)]}function br(t){if(t.length>2)throw new e(`INVALID_ARGS`,`alert accepts at most action and timeout arguments.`);return S({action:xr(t[0]),timeoutMs:Xn(t[1],`alert timeout`)})}function xr(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 Sr=U(`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`),W=U(`snapshotDepth`,`snapshotScope`,`snapshotRaw`),Cr=U(`metroProjectRoot`,`kind`,`metroKind`,`metroPublicBaseUrl`,`metroProxyBaseUrl`,`metroBearerToken`,`metroPreparePort`,`metroListenHost`,`metroStatusHost`,`metroStartupTimeoutMs`,`metroProbeTimeoutMs`,`metroRuntimeFile`,`metroNoReuseExisting`,`metroNoInstallDeps`),wr=U(`metroHost`,`metroPort`,`bundleUrl`),Tr=U(`count`,`intervalMs`,`holdMs`,`jitterPx`,`doubleTap`),Er=U(`settle`,`settleQuietMs`,`timeoutMs`),Dr=U(`replayUpdate`,`replayEnv`),Or=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`]),Ar=`diff`,jr=H(Ar,`Diff accessibility snapshots.`,{kind:d(_({type:`string`,const:`snapshot`})),out:f(),interactiveOnly:h(),depth:m(),scope:f(),raw:h()}),Mr=P({name:Ar,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]`,helpDescription:`Diff accessibility snapshot or compare screenshots pixel-by-pixel. Live iOS simulator screenshot diffs normalize status-bar chrome by default; use screenshot --normalize-status-bar when capturing reusable baselines.`,summary:`Diff snapshot or screenshot`,positionalArgs:[`kind`,`current?`],allowedFlags:[...Sr,`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{...E(n),kind:`snapshot`,out:n.out,interactiveOnly:n.snapshotInteractiveOnly,depth:n.snapshotDepth,scope:n.snapshotScope,raw:n.snapshotRaw}},daemonWriter:w(s.diff,e=>[N(e.kind,`diff requires kind`)])}),Nr=`screenshot`,Pr=H(Nr,`Capture a screenshot.`,{path:f(`Output path.`),overlayRefs:h(),pixelDensity:m(`Output screenshot pixel density in pixels per logical point.`,{min:1}),fullscreen:h(),maxSize:m(),stabilize:h(),normalizeStatusBar:h(),surface:g(te)}),Fr=P({name:Nr,metadata:Pr,definition:R(Pr,(e,t)=>e.capture.screenshot(t)),cliSchema:{helpDescription:`Capture screenshot (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, --max-size 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)`,summary:`Capture screenshot with optional density, full-page, desktop, downscale, or ref overlay modes`,positionalArgs:[`path?`],allowedFlags:we},cliReader:(e,t)=>({...E(t),path:e[0]??t.out,...De(t)}),daemonWriter:e=>T(s.screenshot,A(e.path),{...e,...de(e)})}),Ir=`settings`,Lr=H(Ir,`Change OS settings and app permissions.`,{setting:d(f()),state:d(f()),app:f(),latitude:p(),longitude:p(),permission:f(),mode:g([`full`,`limited`])}),Rr=P({name:Ir,metadata:Lr,definition:R(Lr,(e,t)=>e.settings.update(t)),cliSchema:{usageOverride:Je,listUsageOverride:`settings [area] [options]`,helpDescription:`Toggle OS settings, animation scales, appearance, and app permissions (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)`,summary:`Change OS settings and app permissions`,positionalArgs:[`setting`,`state`,`target?`,`mode?`]},cliReader:(e,t)=>zr(e,t),daemonWriter:w(s.settings,e=>Br(e))});function zr(t,n){let r=Nn(n),i=t[0],a=t[1];if(O(i,Ur)&&O(a,Wr))return{...r,setting:i,state:a};if(i===`location`&&a===`set`)return{...r,setting:i,state:a,latitude:Xe(t[2],`latitude`),longitude:Xe(t[3],`longitude`)};if(i===`appearance`&&O(a,Gr)||O(i,Kr)&&O(a,qr)||i===`fingerprint`&&O(a,Jr))return{...r,setting:i,state:a};if(i===`permission`&&O(a,Yr))return{...r,setting:i,state:a,permission:Vr(t[2]),mode:Hr(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 Br(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 Vr(t){if(O(t,Xr))return t;throw new e(`INVALID_ARGS`,`settings permission requires a permission target.`)}function Hr(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 Ur=D(`wifi`,`airplane`,`location`,`animations`),Wr=D(`on`,`off`),Gr=D(`light`,`dark`,`toggle`),Kr=D(`faceid`,`touchid`),qr=D(`match`,`nonmatch`,`enroll`,`unenroll`),Jr=D(`match`,`nonmatch`),Yr=D(`grant`,`deny`,`reset`),Xr=D(`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`,`accessibility`,`screen-recording`,`input-monitoring`);function Zr(e){if(!Array.isArray(e)||e.length===0)return e;let t=gt(e);return e.map(e=>{let n=Qr(e,t,e=>e.label),r=Qr(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 Qr(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 $r(e){let t=Ce(e.raw||!Array.isArray(e.result.nodes)?e.result:{...e.result,nodes:Zr(e.result.nodes)});return{data:t,jsonData:ti(t),stderr:e.result.snapshotDiagnostics?.warning?`${e.result.snapshotDiagnostics.warning}\n`:void 0,text:xe(t,{raw:e.raw,flatten:e.interactiveOnly,scoped:typeof e.scope==`string`&&e.scope.trim().length>0,depthLimited:typeof e.depth==`number`})}}const ei={snapshot:({input:e,result:t})=>$r({result:t,raw:e.raw,interactiveOnly:e.interactiveOnly,scope:e.scope,depth:e.depth}),wait:B,alert:B};function ti(e){let{unchanged:t,...n}=e;return n}const ni=`snapshot`,ri=H(ni,`Capture an accessibility snapshot.`,{interactiveOnly:h(),depth:m(),scope:f(),raw:h(),forceFull:h(),timeoutMs:m(`Maximum wall-clock time for the snapshot command.`),noRecord:h(`Do not record this action.`),record:h(`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.`)}),ii=P({name:ni,metadata:ri,definition:R(ri,(e,t)=>e.capture.snapshot(t)),cliSchema:{usageOverride:`snapshot [--diff] [-i] [-d <depth>] [-s <scope>] [--raw] [--force-full] [--timeout <ms>]`,helpDescription:`Capture accessibility tree or diff against the previous session baseline. 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.`,summary:`Capture accessibility tree or diff against the previous session baseline`,allowedFlags:[`snapshotDiff`,...Sr,`snapshotForceFull`,`timeoutMs`,`record`]},cliReader:(e,t)=>({...E(t),...Mn(t),interactiveOnly:t.snapshotInteractiveOnly,depth:t.snapshotDepth,scope:t.snapshotScope,raw:t.snapshotRaw,forceFull:t.snapshotForceFull,timeoutMs:t.timeoutMs}),daemonWriter:w(s.snapshot),cliOutputFormatter:ei.snapshot}),ai=[`duration`,`text`,`ref`,`selector`,`stable`],oi=`wait`,si=H(oi,`Wait for duration, text, ref, selector, or stable UI.`,{kind:g(ai),durationMs:m(),text:f(),ref:f(),selector:f(),stable:h(),quietMs:m(),timeoutMs:m(),depth:m(),scope:f(),raw:h()}),ci=P({name:oi,metadata:si,definition:R(si,(e,t)=>e.command.wait(li(t))),cliSchema:{usageOverride:`wait <ms>|text <text>|@ref|<selector>|stable [quietMs] [timeoutMs]`,positionalArgs:[`durationOrSelector`,`timeoutMs?`],allowsExtraPositionals:!0,allowedFlags:[...W]},cliReader:(e,t)=>ui(e,t),daemonWriter:w(s.wait,e=>di(e)),cliOutputFormatter:B});function li(e){mn(e,`kind`,ai);let t={...e};return delete t.kind,t}function ui(t,n){let r=$e(t);if(!r)throw new e(`INVALID_ARGS`,`wait requires <ms>, text <text>, @ref, <selector> [timeoutMs], or stable [quietMs] [timeoutMs].`);let i={...Nn(n),...Fn(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,...fi(r.timeoutMs)}}return r.kind===`ref`?{...i,ref:r.rawRef,...fi(r.timeoutMs)}:r.kind===`stable`?{...i,stable:!0,...pi(r.quietMs),...fi(r.timeoutMs)}:{...i,selector:r.selectorExpression,...fi(r.timeoutMs)}}function di(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(!tt(r))throw new e(`INVALID_ARGS`,`Invalid wait selector: ${r}`);return[r,...n]}function fi(e){return e===null?{}:{timeoutMs:e}}function pi(e){return e===null?{}:{quietMs:e}}const mi=F({name:`capture`,commands:[ii,Fr,Mr,ci,vr,Rr]});function hi(e){let t=[e.outPath,e.message];t.push(..._i(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
|
|
4
|
-
`)}`}function
|
|
5
|
-
`)}}function Ja(e){return{data:{device:ce(e.device),availableCommands:e.availableCommands},text:[`${oo(e.device)} supports ${e.availableCommands.length} commands:`,e.availableCommands.join(` `)].join(`
|
|
6
|
-
`)}}function
|
|
1
|
+
import{_ as e,n as t,t as n}from"./sdk-contracts.js";import{At as r,D as i,E as a,Et as o,G as s,J as c,K as ee,Mt as te,Nt as ne,Pt as re,Q as ie,R as ae,S as oe,St as se,Tt as ce,V as le,X as ue,Y as de,Z as fe,b as pe,d as me,dt as he,jt as ge,m as _e,ot as ve,q as ye,ut as be,wt as xe,x as Se}from"./screenshot-geometry.js";import{A as Ce,D as we,Dt as Te,Nt as Ee,Vt as De,_ as Oe,d as ke,dt as Ae,f as je,ft as Me,g as Ne,gt as Pe,ht as Fe,i as Ie,kt as Le,m as Re,mt as ze,p as Be,pn as l,r as Ve,sn as He,u as Ue,wn as We,xt as Ge,yt as Ke}from"./sdk-batch-runner.js";import{n as qe,t as Je}from"./sdk-device.js";import{At as Ye,Bt as Xe,Dt as Ze,Et as Qe,Ft as $e,Gt as et,It as tt,Kt as u,Lt as nt,Nt as rt,Ot as it,Pt as at,Qt as ot,Ut as st,Yt as ct,_n as lt,a as ut,an as dt,bn as ft,cn as pt,dn as mt,in as ht,jt as gt,kt as _t,ln as vt,mt as yt,n as bt,o as xt,on as St,r as Ct,sn as wt,t as Tt,un as Et,vt as Dt,yt as Ot,zt as kt}from"./viewport-dimension.js";import{a as At}from"./sdk-remote-config.js";import{a as jt,d as Mt,t as Nt,u as Pt}from"./device.js";const Ft=[{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:ct,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:`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)`}],It=[{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:At,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`}],Lt=[{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:st,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`,...gt],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`}],Rt=[{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:`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`},...o,{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)`}],zt=[...It,...Lt,...Ft,...Rt],Bt=new Map;for(let e of zt)for(let t of e.names)Bt.set(t,e);function Vt(e){return Bt.get(e)}function Ht(){return zt}const Ut=new Set(Ht().map(e=>e.key));function Wt(e){let t=lt(e);return We({stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,...ft(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,snapshotForceFull:e.forceFull,...r(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 Gt(e,t){return{...Wt(e),...t}}function Kt(e,t){let n=e.inputSchema.properties;if(!n)return{};let r={},i=t;for(let e of Object.keys(n)){if(!Ut.has(e))continue;let t=i[e];qt(t)&&(r[e]=t)}return r}function qt(e){return typeof e==`boolean`||typeof e==`number`||typeof e==`string`}const Jt=[`ref`,`selector`,`point`];function Yt(e,t=[]){return{type:`object`,properties:{...Fn(),...e},...t.length>0?{required:t}:{},additionalProperties:!1}}function Xt(e){return{type:`object`,description:e,properties:{x:{type:`number`},y:{type:`number`}},required:[`x`,`y`],additionalProperties:!1}}function Zt(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function d(e){return{type:`string`,...e?{description:e}:{}}}function Qt(e,t={}){return{type:`number`,...e?{description:e}:{},...t.min===void 0?{}:{minimum:t.min},...t.max===void 0?{}:{maximum:t.max}}}function $t(e){return{type:`integer`,...e?{description:e}:{}}}function en(e){return{type:`boolean`,...e?{description:e}:{}}}function tn(e){return{type:`array`,items:{type:`string`},...e?{description:e}:{}}}function nn(e){return{type:`object`,additionalProperties:!0,...e?{description:e}:{}}}function f(e){return{...e,required:!0}}function p(e){return C(d(e),b)}function rn(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 C(Qt(e,t),(e,n)=>Me(e,n,t))}function h(e,t={}){return C(An(e,t),(e,n)=>Ae(e,n,t))}function g(e){return C(en(e),Sn)}function _(e,t){return C(Zt(e,t),(t,n)=>wn(t,n,e))}function an(e){return C(nn(e),Nn)}function on(e){return C(tn(e),Pn)}function v(e){return C(e,(e,t)=>e[t])}function sn(e,t){return C(e,t)}function cn(){return C(In(),(e,t)=>e[t]===void 0?void 0:_n(e,t))}function ln(){return C(Ln(),(e,t)=>e[t]===void 0?void 0:vn(e,t))}function un(e){return C(Xt(e),(e,t)=>e[t]===void 0?void 0:yn(e,t))}function dn(){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 fn(){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 y(e){return Yt(jn(e),Mn(e))}function pn(t,n){let r=mn(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=hn(r,{readTargetAlias:!Object.hasOwn(n,`target`)});return S({...a,...x(a),...i})}function mn(t){if(t==null)return{};if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected object arguments.`);return t}function hn(e,t={}){return{session:b(e,`session`),platform:wn(e,`platform`,qe),deviceTarget:gn(e,t),device:b(e,`device`),udid:b(e,`udid`),serial:b(e,`serial`),iosSimulatorDeviceSet:b(e,`iosSimulatorDeviceSet`),iosXctestrunFile:b(e,`iosXctestrunFile`),iosXctestDerivedDataPath:b(e,`iosXctestDerivedDataPath`),iosXctestEnvDir:b(e,`iosXctestEnvDir`),androidDeviceAllowlist:b(e,`androidDeviceAllowlist`),noRecord:Sn(e,`noRecord`),daemonBaseUrl:b(e,`daemonBaseUrl`),daemonAuthToken:b(e,`daemonAuthToken`),tenant:b(e,`tenant`),runId:b(e,`runId`),leaseId:b(e,`leaseId`),cwd:b(e,`cwd`),debug:Sn(e,`debug`)}}function gn(t,n){let r=wn(t,`deviceTarget`,Je);if(n.readTargetAlias===!1||t.target===void 0)return r;let i=wn(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 _n(e,t){let n=zn(e,t),r=Cn(n,`kind`,Jt);switch(r){case`ref`:return{kind:r,ref:bn(n,`ref`),label:b(n,`label`)};case`selector`:return{kind:r,selector:bn(n,`selector`)};case`point`:return{kind:r,x:xn(n,`x`),y:xn(n,`y`)}}}function vn(e,t){let n=zn(e,t),r=Cn(n,`kind`,[`ref`,`selector`]);return r===`ref`?{kind:r,ref:bn(n,`ref`),label:b(n,`label`)}:{kind:r,selector:bn(n,`selector`)}}function yn(e,t){let n=zn(e,t);return{x:xn(n,`x`),y:xn(n,`y`)}}function bn(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 b(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 xn(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 Sn(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 Cn(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 wn(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 x(e){return S({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 Tn(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 En(e){switch(e.kind){case`ref`:return{ref:e.ref,label:e.label};case`selector`:return{selector:e.selector}}}function Dn(e){return{count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap}}function On(e){return{depth:e.depth,scope:e.scope,raw:e.raw}}function kn(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 S(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function C(e,t){return{schema:e,required:!1,read:t}}function An(e,t){return{...$t(e),...t.min===void 0?{}:{minimum:t.min},...t.max===void 0?{}:{maximum:t.max}}}function jn(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>!e.retired).map(([e,t])=>[e,t.schema]))}function Mn(e){return Object.entries(e).flatMap(([e,t])=>t.required?[e]:[])}function Nn(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 Pn(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 Fn(){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 In(){return{oneOf:[...Rn(),{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 Ln(){return{oneOf:Rn(),description:`UI element target by snapshot ref or selector expression.`}}function Rn(){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 zn(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 w(e,t){return n=>T(e,t?t(n):[],n)}function T(e,t,n,r){return{command:e,positionals:t,...r?{input:r}:{},options:Bn(n)}}function Bn(e){let t=Vn(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 Vn(e){return e===`mobile`||e===`tv`||e===`desktop`?e:void 0}function E(e){return S({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 Hn(e){return S({record:e.record})}function Un(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 Wn(e){return S({depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw})}function Gn(e){return{depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw}}function Kn(e){return S({settle:e.settle,settleQuietMs:e.settleQuietMs,timeoutMs:e.timeoutMs})}function qn(e){return S({count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap})}function Jn(e){if(`ref`in e&&e.ref!==void 0)return S({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 Yn(t){let n=Zn(t);if(typeof n.ref==`string`)return[n.ref,...$n(n.label)];if(typeof n.selector==`string`)return[n.selector];if(n.kind===`point`||n.x!==void 0||n.y!==void 0)return[String(Qn(n.x,`x`)),String(Qn(n.y,`y`))];throw new e(`INVALID_ARGS`,`interaction requires @ref, selector, or point target`)}function Xn(t){let n=Zn(t);if(typeof n.ref==`string`)return[n.ref,...$n(n.label)];if(typeof n.selector==`string`)return[n.selector];throw new e(`INVALID_ARGS`,`element command requires @ref or selector target`)}function Zn(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 Qn(t,n){if(typeof t!=`number`||!Number.isFinite(t))throw new e(`INVALID_ARGS`,`point target requires numeric ${n}.`);return t}function $n(e){return typeof e==`string`&&e.length>0?[e]:[]}function er(t){let n=Fe(t);if(!n.ok)throw new e(n.code,n.message);return`ref`in n?{ref:n.ref,label:ir(t.slice(1))}:{selector:n.selector}}function tr(t){let n=Pe(t);if(!n.ok)throw new e(n.code,n.message);return n.format}function nr(t,n={}){let r=De(t,n);if(!r)throw new e(`INVALID_ARGS`,ze);return r}function rr(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 ir(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 ar(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}function or(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 sr(e){return e===void 0?void 0:Number(e)}function k(e){return e===void 0?[]:[e]}function A(e){return e===void 0?[]:[String(e)]}function j(t,n){if(t===void 0||t===``)throw new e(`INVALID_ARGS`,n);return t}function M(t,n){if(typeof t!=`string`||t.length===0)throw new e(`INVALID_ARGS`,n);return t}function cr(e){return dr(e.description,e.cliDetail)}function lr(e){return dr(e.description,e.mcpDetail)}function ur(e,t){return{...e,description:t}}function dr(e,t){return t?`${e} ${t}`:e}function N(e){let t=ur(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 P(e){let t={},n={},r={},i={},a={};for(let o of e.commands){F(t,`CLI schema`,o.name,o.cliSchema);let e=o.definition.projection?.clientMethod??o.clientMethod;e&&F(n,`client command method`,e,o.name),F(r,`CLI reader`,o.name,o.cliReader),o.daemonWriter&&F(i,`daemon writer`,o.name,o.daemonWriter),o.cliOutputFormatter&&F(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 fr(e){let t={};for(let n of e)n.projection&&F(t,`command output schema`,n.name,n.projection.outputSchema);return t}function F(e,t,n,r){if(Object.hasOwn(e,n))throw Error(`Duplicate command family ${t}: ${n}`);e[n]=r}function I(e){return e}function L(e,t,n){return{...e,run:t,invoke:async(n,r)=>await t(n,e.readInput(r)),...n?{projection:n}:{}}}function R(e){return({result:t})=>e(t)}const z=R(B);function B(e){return{data:e,text:mt(e)}}function pr(e,t){if(!(typeof e!=`string`||e.length===0)&&typeof t==`number`)return`@${e.startsWith(`@`)?e.slice(1):e}~s${t}`}function mr(e){let t=[`Batch completed: ${e.executed}/${e.total} steps in ${e.totalDurationMs}ms`];for(let n of e.results)t.push(gr(n));return{data:e,text:t.join(`
|
|
2
|
+
`)}}const hr={batch:R(mr)};function gr(e){let t=mt(e.data)??e.command;return`${e.step}. OK ${t} (${e.durationMs}ms)`}function _r(e=Ve){let t=vr(e);return I({name:`batch`,description:`Execute multiple commands in one daemon request`,inputSchema:y(t),readInput:e=>br(e,t)})}function vr(e){return{steps:f(sn({type:`array`,description:`Structured batch steps. Each step uses a command name and the same input object as that command tool.`,items:yr(e)},(t,n)=>xr(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 yr(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 br(t,n){let r=pn(t,n),i=r.maxSteps??100;if(!ke(i))throw new e(`INVALID_ARGS`,`Invalid batch maxSteps: ${String(r.maxSteps)}`);return Ue(r.steps.length,i),{...r}}function xr(t,n){if(!Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected steps to be an array.`);return t.map((e,t)=>Sr(e,t+1,n))}function Sr(e,t,n){let r=Re(e,t);return kn(r,[`command`,`input`,`runtime`],`Batch step ${t}`),{command:Cr(r,t,n),input:Be(r,t),...wr(r,t)}}function Cr(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 wr(e,t){let n=je(e.runtime,t);return n===void 0?{}:{runtime:n}}function Tr(e){return t=>T(u.batch,[],{...t,batchSteps:Er(t.steps,e),batchOnError:t.onError,batchMaxSteps:t.maxSteps})}function Er(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)=>Dr(e,t+1,n))}function Dr(e,t,n){let r=Re(e,t),i=Or(r,t),a=Be(r,t),o=je(r.runtime,t),s=n(i,a,t);return{command:s.command,positionals:s.positionals,...s.input?{input:s.input}:{},flags:Gt(s.options,s.metadataFlags),runtime:o??s.options.runtime}}function Or(e,t){return Ie(e.command,t)}const kr=_r(),Ar=P({name:`batch`,clientSurface:!1,commands:[N({name:`batch`,text:{summary:`Run multiple commands`},metadata:kr,definition:L(kr,(e,t)=>e.batch.run(jr(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)=>({...E(t),steps:t.batchSteps??[],onError:t.batchOnError,maxSteps:t.batchMaxSteps,out:t.out}),cliOutputFormatter:hr.batch})]});function jr(e){return{...x(e),steps:e.steps,onError:e.onError,maxSteps:e.maxSteps,out:e.out}}function V(e,t,n){return I({name:e,description:t,inputSchema:y(n),readInput:e=>pn(e,n)})}const Mr=`alert`,Nr=V(Mr,`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:_(he),timeoutMs:h()}),Pr=N({name:Mr,text:{summary:`Inspect, accept, or dismiss a platform alert`},metadata:Nr,definition:L(Nr,(e,t)=>e.command.alert(t)),cliSchema:{usageOverride:`alert [get|accept|dismiss|wait] [timeout]`,positionalArgs:[`action?`,`timeout?`]},cliReader:(e,t)=>({...E(t),...Ir(e)}),daemonWriter:w(u.alert,e=>Fr(e)),cliOutputFormatter:z});function Fr(e){return[e.action??`get`,...A(e.timeoutMs)]}function Ir(t){if(t.length>2)throw new e(`INVALID_ARGS`,`alert accepts at most action and timeout arguments.`);return S({action:Lr(t[0]),timeoutMs:or(t[1],`alert timeout`)})}function Lr(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 H(...e){return e}const Rr=H(`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`),U=H(`snapshotDepth`,`snapshotScope`,`snapshotRaw`),zr=H(`metroProjectRoot`,`kind`,`metroKind`,`metroPublicBaseUrl`,`metroProxyBaseUrl`,`metroBearerToken`,`metroPreparePort`,`metroListenHost`,`metroStatusHost`,`metroStartupTimeoutMs`,`metroProbeTimeoutMs`,`metroRuntimeFile`,`metroNoReuseExisting`,`metroNoInstallDeps`),Br=H(`metroHost`,`metroPort`,`bundleUrl`),Vr=H(`count`,`intervalMs`,`holdMs`,`jitterPx`,`doubleTap`),Hr=H(`settle`,`settleQuietMs`,`timeoutMs`),Ur=H(`replayUpdate`,`replayEnv`),Wr=H(`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`),Gr=new Set([`json`,`config`,`help`,`version`,`verbose`,`cost`,`responseLevel`]),Kr=`diff`,qr=V(Kr,`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()}),Jr=N({name:Kr,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:qr,definition:L(qr,(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:[...Rr,`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{...E(n),kind:`snapshot`,out:n.out,interactiveOnly:n.snapshotInteractiveOnly,depth:n.snapshotDepth,scope:n.snapshotScope,raw:n.snapshotRaw}},daemonWriter:w(u.diff,e=>[M(e.kind,`diff requires kind`)])}),Yr=`screenshot`,Xr=V(Yr,`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.`,ce),maxSize:rn(se.migration.screenshot),stabilize:g(),normalizeStatusBar:g(),surface:_(st)}),Zr=N({name:Yr,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:Xr,definition:L(Xr,(e,t)=>e.capture.screenshot(t)),cliSchema:{positionalArgs:[`path?`],allowedFlags:xe},cliReader:(e,t)=>({...E(t),path:e[0]??t.out,...te(t)}),daemonWriter:e=>(ne(`screenshot`,e),re(e),T(u.screenshot,k(e.path),{...e,...ge(e)}))}),Qr=`settings`,$r=V(Qr,`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`])}),ei=N({name:Qr,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:$r,definition:L($r,(e,t)=>e.settings.update(t)),cliSchema:{usageOverride:_e,listUsageOverride:`settings [area] [options]`,positionalArgs:[`setting`,`state`,`target?`,`mode?`]},cliReader:(e,t)=>ti(e,t),daemonWriter:w(u.settings,e=>ni(e))});function ti(t,n){let r=Un(n),i=t[0],a=t[1];if(O(i,ai)&&O(a,oi))return{...r,setting:i,state:a};if(i===`location`&&a===`set`)return{...r,setting:i,state:a,latitude:me(t[2],`latitude`),longitude:me(t[3],`longitude`)};if(i===`appearance`&&O(a,si)||O(i,ci)&&O(a,li)||i===`fingerprint`&&O(a,ui))return{...r,setting:i,state:a};if(i===`permission`&&O(a,di))return{...r,setting:i,state:a,permission:ri(t[2]),mode:ii(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 ni(e){return e.setting===`clear-app-state`?[e.setting,...k(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,...k(e.mode)]:[e.setting,e.state]}function ri(t){if(O(t,fi))return t;throw new e(`INVALID_ARGS`,`settings permission requires a permission target.`)}function ii(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 ai=D(`wifi`,`airplane`,`location`,`animations`),oi=D(`on`,`off`),si=D(`light`,`dark`,`toggle`),ci=D(`faceid`,`touchid`),li=D(`match`,`nonmatch`,`enroll`,`unenroll`),ui=D(`match`,`nonmatch`),di=D(`grant`,`deny`,`reset`),fi=D(`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`,`accessibility`,`screen-recording`,`input-monitoring`);function pi(e){if(!Array.isArray(e)||e.length===0)return e;let t=He(e);return e.map(e=>{let n=mi(e,t,e=>e.label),r=mi(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 mi(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 hi(e){let t=Et(e.raw||!Array.isArray(e.result.nodes)?e.result:{...e.result,nodes:pi(e.result.nodes)});return{data:t,jsonData:_i(t),stderr:e.result.snapshotDiagnostics?.warning?`${e.result.snapshotDiagnostics.warning}\n`:void 0,text:yt(t,{raw:e.raw,flatten:e.interactiveOnly,scoped:typeof e.scope==`string`&&e.scope.trim().length>0,depthLimited:typeof e.depth==`number`})}}const gi={snapshot:({input:e,result:t})=>hi({result:t,raw:e.raw,interactiveOnly:e.interactiveOnly,scope:e.scope,depth:e.depth}),wait:z,alert:z};function _i(e){let{unchanged:t,...n}=e;return n}const vi=`snapshot`,yi=V(vi,`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(),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.`)}),bi=N({name:vi,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:yi,definition:L(yi,(e,t)=>e.capture.snapshot(t)),cliSchema:{usageOverride:`snapshot [--diff] [-i] [-d <depth>] [-s <scope>] [--raw] [--force-full] [--timeout <ms>]`,allowedFlags:[`snapshotDiff`,...Rr,`snapshotForceFull`,`timeoutMs`,`record`]},cliReader:(e,t)=>({...E(t),...Hn(t),interactiveOnly:t.snapshotInteractiveOnly,depth:t.snapshotDepth,scope:t.snapshotScope,raw:t.snapshotRaw,forceFull:t.snapshotForceFull,timeoutMs:t.timeoutMs}),daemonWriter:w(u.snapshot),cliOutputFormatter:gi.snapshot}),xi=[`duration`,`text`,`ref`,`selector`,`stable`],Si=`wait`,Ci=V(Si,`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:_(xi),durationMs:h(),text:p(),ref:p(),selector:p(),stable:g(),quietMs:h(),timeoutMs:h(),depth:h(),scope:p(),raw:g()}),wi=N({name:Si,text:{summary:`Wait for a duration, text, selector, or stable UI`},metadata:Ci,definition:L(Ci,(e,t)=>e.command.wait(Ti(t))),cliSchema:{usageOverride:`wait <ms>|text <text>|@ref|<selector>|stable [quietMs] [timeoutMs]`,positionalArgs:[`durationOrSelector`,`timeoutMs?`],allowsExtraPositionals:!0,allowedFlags:[...U]},cliReader:(e,t)=>Ei(e,t),daemonWriter:w(u.wait,e=>Di(e)),cliOutputFormatter:z});function Ti(e){wn(e,`kind`,xi);let t={...e};return delete t.kind,t}function Ei(t,n){let r=we(t);if(!r)throw new e(`INVALID_ARGS`,`wait requires <ms>, text <text>, @ref, <selector> [timeoutMs], or stable [quietMs] [timeoutMs].`);let i={...Un(n),...Gn(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,...Oi(r.timeoutMs)}}return r.kind===`ref`?{...i,ref:r.rawRef,...Oi(r.timeoutMs)}:r.kind===`stable`?{...i,stable:!0,...ki(r.quietMs),...Oi(r.timeoutMs)}:{...i,selector:r.selectorExpression,...Oi(r.timeoutMs)}}function Di(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=A(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=A(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(!Ce(r))throw new e(`INVALID_ARGS`,`Invalid wait selector: ${r}`);return[r,...n]}function Oi(e){return e===null?{}:{timeoutMs:e}}function ki(e){return e===null?{}:{quietMs:e}}const Ai=P({name:`capture`,commands:[bi,Zr,Jr,wi,Pr,ei]});function ji(e){let t=[e.outPath,e.message];t.push(...Ni(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 Mi={debug:R(ji)};function Ni(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 Pi=`debug`,Fi=V(Pi,`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.`)}),Ii=P({name:`debugging`,commands:[N({name:Pi,text:{summary:`Symbolicate Apple crash artifacts`},metadata:Fi,definition:L(Fi,(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)=>({...E(t),action:Li(e[0]),artifact:t.artifact,dsym:t.dsym,searchPath:t.searchPath,out:t.out}),cliOutputFormatter:Mi.debug})]});function Li(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 Ri=()=>g(`Capture cheap post-action evidence (AX digest, node counts, changedFromBefore) instead of a follow-up snapshot.`),zi=()=>({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 W(e){return{...Oe(e)?{verify:Ri()}:{},...Ne(e)?zi():{}}}function Bi(e){let t=[];return Oe(e)&&t.push(`verify`),Ne(e)&&t.push(...Hr),t}const Vi=[`click`,`focus`,`exists`,`list`,`getText`,`getAttrs`,`wait`,`fill`,`type`],Hi={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.`},Ui={target:f(cn()),button:_(ve,`Pointer button for platforms that support mouse buttons.`),...dn(),...fn(),...W(`click`)},Wi={target:f(cn()),...dn(),...fn(),...W(`press`)},Gi={target:f(cn()),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."),...dn(),...W(`fill`)},Ki={target:f(cn()),durationMs:h(`Long press duration in milliseconds.`,{min:0}),...dn(),...W(`longpress`)},qi={from:f(un(`Swipe start point.`)),to:f(un(`Swipe end point.`)),count:h(`Number of swipe repetitions.`,{min:1,max:200}),pauseMs:h(`Pause between repeated swipes.`,{min:0,max:fe}),pattern:_(ue)},Ji={x:f(m(`X coordinate.`)),y:f(m(`Y coordinate.`))},Yi={text:f(p(`Text to type.`)),delayMs:h(`Delay between typed characters.`,{min:0})},Xi={direction:f(_(de)),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:i}),...W(`scroll`)},Zi=()=>({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.`)}),Qi={format:f(_([`text`,`attrs`])),target:f(ln()),...dn(),...Zi()},$i={predicate:f(_([`visible`,`hidden`,`exists`,`editable`,`selected`,`focused`,`text`])),selector:f(p()),value:p(),...dn(),...Zi()},ea={locator:_(Te),query:f(p()),action:_(Vi),value:p(),timeoutMs:h(),first:g(),last:g(),depth:h(),raw:g(),...Zi()},ta={kind:f(_(ee,`Gesture variant.`)),direction:_(c,`Fling direction.`),preset:_(ie,`Swipe preset.`),origin:un(`Gesture origin point.`),delta:un(`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})},na=[I({name:`click`,description:Hi.click,inputSchema:y(Ui),readInput:e=>pn(e,Ui)}),I({name:`press`,description:Hi.press,inputSchema:y(Wi),readInput:e=>pn(e,Wi)}),I({name:`fill`,description:Hi.fill,inputSchema:y(Gi),readInput:e=>pn(e,Gi)}),G(`longpress`,Ki),G(`swipe`,qi),G(`focus`,Ji),G(`type`,Yi),G(`scroll`,Xi),G(`get`,Qi),G(`is`,$i),G(`find`,ea),I({name:`gesture`,description:Hi.gesture,inputSchema:y(ta),readInput:ra})];function ra(e){let t=mn(e);return{...hn(t),...ye(t)}}function G(e,t){return V(e,Hi[e],t)}const ia={gesture:oa},aa={gesture:e=>{let t=ra(e);return T(u.gesture,[],e,S(t))}};function oa(e,t){return{...E(t),...le(e,t.pointerCount)}}const K={click:(e,t)=>({...E(t),...Wn(t),...qn(t),...Kn(t),target:Jn(xt(e)),button:t.clickButton,verify:t.verify}),press:(e,t)=>({...E(t),...Wn(t),...qn(t),...Kn(t),target:Jn(xt(e)),verify:t.verify}),longpress:(e,t)=>{let n=sa(e);return{...E(t),...Wn(t),...Kn(t),target:Jn(n),durationMs:n.durationMs}},swipe:(e,t)=>({...E(t),...s(e,{count:t.count,pauseMs:t.pauseMs,pattern:t.pattern})}),focus:(e,t)=>({...E(t),x:Number(e[0]),y:Number(e[1])}),type:(e,t)=>({...E(t),text:e.join(` `),delayMs:t.delayMs}),fill:(e,t)=>{let n=ut(e);return{...E(t),...Wn(t),...Kn(t),target:Jn(n.target),text:n.text,delayMs:t.delayMs,recordAs:t.recordAs,verify:t.verify}},scroll:(e,t)=>({...E(t),...Kn(t),direction:da(e[0]),amount:sr(e[1]),pixels:t.pixels,durationMs:t.durationMs}),get:(e,t)=>({...E(t),...Hn(t),...Wn(t),format:tr(e[0]),target:Jn(er(e.slice(1)))})},q={click:e=>T(u.click,Yn(e),{...e,clickButton:e.button}),press:w(u.press,e=>Yn(e)),longpress:w(u.longPress,e=>ca(e)),swipe:e=>(ae(e),T(u.swipe,[],e,{from:e.from,to:e.to,count:e.count,pauseMs:e.pauseMs,pattern:e.pattern})),focus:w(u.focus,e=>[String(e.x),String(e.y)]),type:w(u.type,e=>la(e)),fill:w(u.fill,e=>ua(e)),scroll:w(u.scroll,e=>[M(e.direction,`scroll requires direction`),...A(e.amount)]),get:w(u.get,e=>[M(e.format,`get requires format`),...Xn(e)])};function sa(e){let t=fa(e);return{...xt(t.target),...t.durationMs===void 0?{}:{durationMs:t.durationMs}}}function ca(e){return[...Yn(e),...A(e.durationMs)]}function la(e){return[e.text]}function ua(e){return[...Yn(e),e.text]}function da(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 fa(e){if(ar(e[0])&&ar(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&&ar(t)?{target:e.slice(0,-1),durationMs:Number(t)}:{target:e}}const pa=R(e=>{let t=B(e);return{data:t.data,text:ma(t.text,e)}});function ma(e,t){let n=typeof t.warning==`string`?`\nWarning: ${t.warning}`:``;return`${e??``}${n}${ha(t.settle)}`}function ha(e){if(!e||typeof e!=`object`)return``;let t=e,n=[ya(t),...ga(t),...va(t)];return t.hint&&n.push(`hint: ${t.hint}`),`\n${n.join(`
|
|
4
|
+
`)}`}function ga(e){let t=e.diff,n=(t?.lines??[]).map(t=>`${t.kind===`removed`?`-`:`+`} ${_a(t,e.refsGeneration)}`);return t?.truncated&&n.push(`… changed lines truncated`),n}function _a(e,t){let n=e.text??``,r=pr(e.ref,t);if(!r||!e.ref)return n;let i=`@${e.ref}`;return n.startsWith(`${i} `)?`${r}${n.slice(i.length)}`:n}function va(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=pr(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 ya(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 ba(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)}:Ea(t)}function xa(e){let t=e,n=mt(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:Sa(t.matches,t.refsGeneration)};let r=pr(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)}:Ea(t)}function Sa(e,t){return[`${e.length} match${e.length===1?``:`es`}:`,...e.map(e=>Ca(e,t))].join(`
|
|
5
|
+
`)}function Ca(e,t){let n=e.ref??``,r=n.startsWith(`@`)?n.slice(1):n,i=pr(n,t)??`@${r}`,a=Ot(e.node?.type??`Element`),o=e.node?Dt(e.node,a):``;return`= ${i} [${a}]${o?` "${o}"`:``}`}function wa(e){let t=e;return{data:t,text:`Passed: is ${t.predicate??`assertion`}`}}function Ta(e){let t=e,n=t.ref??``,r=t.x,i=t.y;if(!n||typeof r!=`number`||typeof i!=`number`){let e=Ea(t);return{data:e.data,text:ma(e.text,t)}}return{data:t,text:ma(`Tapped @${n} (${r}, ${i})`,t)}}const J={click:R(Ta),press:R(Ta),fill:pa,longpress:pa,scroll:pa,get:({input:e,result:t})=>ba({result:t,format:e.format}),is:R(wa),find:R(xa)};function Ea(e){return B(e)}const Da={find:(e,t)=>ja(e,t),is:(e,t)=>Ma(e,t)},Oa={is:w(u.is,e=>ka(e)),find:e=>T(u.find,Aa(e),{...e,findFirst:e.first,findLast:e.last})};function ka(e){return[e.predicate,e.selector,...e.predicate===`text`?[e.value]:[]]}function Aa(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`,...A(e.timeoutMs)];case`fill`:case`type`:return[...t,e.action,e.value]}}function ja(t,n){let r={...Pa(n),...Un(n),...Hn(n),first:n.findFirst,last:n.findLast},i=Na(t[0]),a=i!==void 0,o=a?t[1]:t[0],s=a?2:1,c=Ee(t[s]);if(c===void 0)return{...r,locator:i,query:Fa(o)};if(c===`get`){let n=t[s+1];if(n===`text`)return{...r,locator:i,query:Fa(o),action:`getText`};if(n===`attrs`)return{...r,locator:i,query:Fa(o),action:`getAttrs`};throw new e(`INVALID_ARGS`,`find get only supports text or attrs`)}if(c===`wait`)return{...r,locator:i,query:Fa(o),action:`wait`,timeoutMs:sr(t[s+1])};if(c===`fill`||c===`type`)return{...r,locator:i,query:Fa(o),action:c,value:t.slice(s+1).join(` `)};if(c===`click`||c===`focus`||c===`exists`||c===`list`)return{...r,locator:i,query:Fa(o),action:c};throw new e(`INVALID_ARGS`,`Unsupported find action: ${t[s]}`,{hint:Le})}function Ma(t,n){let r={...Gn(n),...Un(n),...Hn(n)},i=Ge(t),a=Ke(i[0]??``);if(!a.ok)throw new e(a.code,a.message,{hint:a.hint});let o=a.predicate,s=nr(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 Na(e){if(e===`text`||e===`label`||e===`value`||e===`role`||e===`id`)return e}function Pa(e){return{depth:e.snapshotDepth,raw:e.snapshotRaw}}function Fa(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:[...U,`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:[...U,`record`]},click:{usageOverride:`click <x y|@ref|selector>`,positionalArgs:[`target`],allowsExtraPositionals:!0,allowedFlags:[...Vr,`clickButton`,...Bi(`click`),...U]},press:{usageOverride:`press <x y|@ref|selector>`,positionalArgs:[`targetOrX`,`y?`],allowsExtraPositionals:!0,allowedFlags:[...Vr,...Bi(`press`),...U]},longpress:{usageOverride:`longpress <x y|@ref|selector> [durationMs]`,positionalArgs:[`targetOrX`,`yOrDurationMs?`,`durationMs?`],allowsExtraPositionals:!0,allowedFlags:[...Bi(`longpress`),...U]},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:[...U,`delayMs`,`recordAs`,...Bi(`fill`)]},scroll:{usageOverride:`scroll <direction|top|bottom> [amount] [--pixels <n>] [--duration-ms <ms>] [--settle]`,positionalArgs:[`directionOrEdge`,`amount?`],allowedFlags:[`pixels`,`durationMs`,...Bi(`scroll`)]}},Ia=L(X(`click`),(e,t)=>e.interactions.click(Ya(t))),La=L(X(`press`),(e,t)=>e.interactions.press(Xa(t))),Ra=L(X(`fill`),(e,t)=>e.interactions.fill(Za(t))),za=L(X(`longpress`),(e,t)=>e.interactions.longPress(Qa(t))),Ba=L(X(`swipe`),(e,t)=>e.interactions.swipe(t)),Va=L(X(`focus`),(e,t)=>e.interactions.focus(t)),Ha=L(X(`type`),(e,t)=>e.interactions.type(t)),Ua=L(X(`scroll`),(e,t)=>e.interactions.scroll(t)),Wa=L(X(`get`),(e,t)=>e.interactions.get(eo(t))),Ga=L(X(`is`),(e,t)=>e.interactions.is(t)),Ka=L(X(`find`),(e,t)=>e.interactions.find(t)),qa=L(X(`gesture`),async(e,t)=>{switch(t.kind){case`pan`:return await e.interactions.pan(to(t));case`fling`:return await e.interactions.fling(ro(t));case`swipe`:return await e.interactions.swipeGesture(io(t));case`pinch`:return await e.interactions.pinch(ao(t));case`rotate`:return await e.interactions.rotateGesture(oo(t));case`transform`:return await e.interactions.transformGesture(so(t));case`drag`:return await e.interactions.drag(no(t))}}),Ja=P({name:`interaction`,clientSurface:!1,commands:[N({name:`click`,text:{summary:`Click or tap a UI target`},metadata:X(`click`),definition:Ia,cliSchema:Y.click,cliReader:K.click,daemonWriter:q.click,cliOutputFormatter:J.click}),N({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:La,cliSchema:Y.press,cliReader:K.press,daemonWriter:q.press,cliOutputFormatter:J.press}),N({name:`fill`,text:{summary:`Replace text in a UI input`},metadata:X(`fill`),definition:Ra,cliSchema:Y.fill,cliReader:K.fill,daemonWriter:q.fill,cliOutputFormatter:J.fill}),N({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:za,cliSchema:Y.longpress,cliReader:K.longpress,daemonWriter:q.longpress,cliOutputFormatter:J.longpress}),N({name:`swipe`,text:{summary:`Fling between coordinates`},metadata:X(`swipe`),definition:Ba,cliSchema:Y.swipe,cliReader:K.swipe,daemonWriter:q.swipe}),N({name:`focus`,text:{summary:`Focus input at screen coordinates`},metadata:X(`focus`),definition:Va,cliSchema:Y.focus,cliReader:K.focus,daemonWriter:q.focus}),N({name:`type`,text:{summary:`Append text to the focused input`},metadata:X(`type`),definition:Ha,cliSchema:Y.type,cliReader:K.type,daemonWriter:q.type}),N({name:`scroll`,text:{summary:`Scroll in a direction or to an edge`},metadata:X(`scroll`),definition:Ua,cliSchema:Y.scroll,cliReader:K.scroll,daemonWriter:q.scroll,cliOutputFormatter:J.scroll}),N({name:`get`,text:{summary:`Read element text or attributes`},metadata:X(`get`),definition:Wa,cliSchema:Y.get,cliReader:K.get,daemonWriter:q.get,cliOutputFormatter:J.get}),N({name:`is`,text:{summary:`Check a UI predicate on a selector`},metadata:X(`is`),definition:Ga,cliSchema:Y.is,cliReader:Da.is,daemonWriter:Oa.is,cliOutputFormatter:J.is}),N({name:`find`,text:{summary:`Find an element and act`},metadata:X(`find`),definition:Ka,cliSchema:Y.find,cliReader:Da.find,daemonWriter:Oa.find,cliOutputFormatter:J.find}),N({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:qa,cliSchema:Y.gesture,cliReader:ia.gesture,daemonWriter:aa.gesture})]});function X(e){let t=na.find(t=>t.name===e);if(!t)throw Error(`Missing interaction command metadata for ${e}`);return t}function Ya(e){return{...x(e),...Tn(e.target),...On(e),...Dn(e),button:e.button,verify:e.verify,...$a(e)}}function Xa(e){return{...x(e),...Tn(e.target),...On(e),...Dn(e),verify:e.verify,...$a(e)}}function Za(e){return{...x(e),...Tn(e.target),...On(e),text:e.text,delayMs:e.delayMs,recordAs:e.recordAs,verify:e.verify,...$a(e)}}function Qa(e){return{...x(e),...Tn(e.target),...On(e),durationMs:e.durationMs,...$a(e)}}function $a(e){return{settle:e.settle,settleQuietMs:e.settleQuietMs,timeoutMs:e.timeoutMs}}function eo(e){return{...x(e),...En(e.target),...On(e),format:e.format,record:e.record}}function to(e){return{...x(e),x:e.origin.x,y:e.origin.y,dx:e.delta.x,dy:e.delta.y,pointerCount:e.pointerCount,durationMs:e.durationMs}}function no(e){return{...x(e),source:e.source,destination:e.destination,sourceHoldMs:e.sourceHoldMs,moveMs:e.moveMs,destinationHoldMs:e.destinationHoldMs}}function ro(e){return{...x(e),direction:e.direction,x:e.origin.x,y:e.origin.y,distance:e.distance}}function io(e){return{...x(e),preset:e.preset}}function ao(e){return{...x(e),scale:e.scale,x:e.origin?.x,y:e.origin?.y}}function oo(e){return{...x(e),degrees:e.degrees,x:e.origin?.x,y:e.origin?.y}}function so(e){return{...x(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}}let co=!1;function lo(){co=!0}function uo(){let e=co;return co=!1,e}function fo(e){return{data:{devices:e.map(St)},text:e.map(To).join(`
|
|
6
|
+
`)}}function po(e){return{data:{device:St(e.device),availableCommands:e.availableCommands},text:[`${To(e.device)} supports ${e.availableCommands.length} commands:`,e.availableCommands.join(` `)].join(`
|
|
7
|
+
`)}}function mo(e){return{data:{apps:e.result},stderr:e.appsFilter===`all`?`Showing all apps, including system apps.
|
|
7
8
|
`:`Showing user-installed apps. Use --all to include system apps.
|
|
8
9
|
`,text:e.result.length>0?e.result.join(`
|
|
9
|
-
`):e.appsFilter===`all`?`No apps found.`:`No user-installed apps found.`}}function
|
|
10
|
-
`)||null}}function
|
|
11
|
-
`):e.message??`No daemon artifacts available.`};let t=[e.message??`No cloud artifacts available for ${e.provider}.`],n=
|
|
10
|
+
`):e.appsFilter===`all`?`No apps found.`:`No user-installed apps found.`}}function ho(e){if(`savedScript`in e)return{data:e,text:`Published script: ${e.savedScript}\nSession remains active: ${e.session}\nActions: ${e.actionCount}`};if(`stateDir`in e)return{data:e,text:e.stateDir};let t={sessions:e.sessions.map(vt)};return{data:t,text:JSON.stringify(t,null,2)}}function go(e){let t=pt(e),n=[mt(t)].filter(e=>!!e);typeof t.sessionStateDir==`string`&&n.push(`Session state: ${t.sessionStateDir}`);for(let t of e.warnings??[])n.push(`Warning: ${t}`);return{data:t,text:n.join(`
|
|
11
|
+
`)||null}}function _o(e){return B(ht(e))}function vo(e){if(yo(e))return{data:e,text:e.artifacts.length>0?e.artifacts.map(Do).join(`
|
|
12
|
+
`):e.message??`No daemon artifacts available.`};let t=[e.message??`No cloud artifacts available for ${e.provider}.`],n=Oo(e);return n&&t.push(`Retry: ${n}`),{data:e,text:e.cloudArtifacts.length>0?e.cloudArtifacts.map(Eo).join(`
|
|
12
13
|
`):t.join(`
|
|
13
|
-
`)}}function
|
|
14
|
-
`)}}const Z={boot:z(ro),shutdown:z(io),devices:z(qa),capabilities:z(Ja),doctor:z(ao),apps:({input:e,result:t})=>Ya({result:t,appsFilter:e.appsFilter}),session:z(Xa),artifacts:z($a),open:z(Za),close:z(Qa),install:z(to),reinstall:z(to),"install-from-source":z(no),prepare:B,viewport:B};function oo(e){let t=e.kind?` ${e.kind}`:``,n=e.target?` target=${e.target}`:``,r=typeof e.booted==`boolean`?` booted=${e.booted}`:``;return`${e.name} (${e.platform}${t}${n})${r}`}function so(e){let t=e.url?` ${e.url}`:``,n=e.availability?` ${e.availability}`:``;return`${e.kind}: ${e.name}${n}${t}`}function co(e){let t=e.artifactType?` (${e.artifactType})`:``;return`${e.filename}${t}: ${e.mimeType} ${e.sizeBytes} bytes id=${e.id}`}function lo(e){if(e.providerSessionId)return`agent-device artifacts ${e.providerSessionId} --provider ${e.provider} --json`}function uo(e){return Array.isArray(e)?e.filter(e=>!!e&&typeof e==`object`&&!Array.isArray(e)):[]}const fo=H(`artifacts`,`List daemon or cloud provider artifacts for an active or completed session.`,{provider:f(`Cloud provider name, for example browserstack or aws-device-farm.`),providerSessionId:f(`Cloud provider session id or ARN.`)}),po=P({name:`artifacts`,metadata:fo,definition:R(fo,(e,t)=>e.sessions.artifacts(t)),cliSchema:{summary:`List daemon or cloud provider session artifacts`,usageOverride:`artifacts [provider-session-id] [--provider <name>]`,positionalArgs:[`provider-session-id?`],allowedFlags:[`provider`,`providerSessionId`]},cliReader:(e,t)=>({...E(t),provider:t.provider,providerSessionId:e[0]??t.providerSessionId}),daemonWriter:w(s.artifacts),cliOutputFormatter:Z.artifacts});function mo(e){let{metroHost:t,metroPort:n,bundleUrl:r,launchUrl:i}=e;if(!(t===void 0&&n===void 0&&r===void 0&&i===void 0))return{metroHost:t,metroPort:n,bundleUrl:r,launchUrl:i}}function ho(e){let{metroHost:t,metroPort:n,bundleUrl:r,launchUrl:i,...a}=e,o=mo({metroHost:t,metroPort:n,bundleUrl:r,launchUrl:i});return o?{...a,runtime:o}:a}const go=H(`apps`,`List installed apps.`,{appsFilter:g([`user-installed`,`all`])}),_o=H(`open`,`Open an app, deep link, URL, or platform surface.`,{app:f(`App name, bundle id, package, or URL.`),url:f(`Optional URL passed with an app shell.`),surface:g(te),activity:f(`Android activity name.`),launchConsole:f(`Launch console mode.`),launchArgs:Yt(`Launch arguments forwarded verbatim to the platform launch command.`),relaunch:h(`Force relaunch.`),saveScript:_({oneOf:[Gt(),u()]}),force:h(`Overwrite an existing --save-script target instead of refusing (alias: --overwrite).`),deviceHub:h(`Use Xcode Device Hub when surfacing Apple simulators.`),testIme:h(`Activate the headless Android test IME for deterministic Unicode text entry (default on for emulators; opt-in on real devices).`),noRecord:h(`Do not record this action.`),metroHost:f(`Session-scoped Metro/debug host hint applied to the opened app.`),metroPort:m(`Session-scoped Metro/debug port hint applied to the opened app. On an emulator/simulator the host defaults to the loopback alias (Android 10.0.2.2, iOS 127.0.0.1) when --metro-host is omitted; physical devices still require an explicit --metro-host.`,{min:1,max:65535}),bundleUrl:f(`Session-scoped bundle URL hint applied to the opened app.`),launchUrl:f(`Session-scoped launch URL hint applied to the opened app.`)}),vo=H(`close`,`Close an app or end the active session.`,{app:f(`Optional app to close.`),shutdown:h(`Shutdown the session/device where supported.`),saveScript:_({oneOf:[Gt(),u()]}),force:h(`Overwrite an existing --save-script target instead of refusing (alias: --overwrite).`)}),yo=R(go,(e,t)=>e.apps.list(t)),bo=R(_o,(e,t)=>e.apps.open(xo(t)));function xo(e){return ho(e)}const So=R(vo,(e,t)=>t.app?e.apps.close(t):e.sessions.close(Fo(t))),Co={helpDescription:`List user-installed apps; use --all to include system/OEM apps`,summary:`List installed apps`,allowedFlags:[`appsFilter`],defaults:{appsFilter:Tt}},wo={helpDescription:`Boot device/simulator; optionally launch app or deep link URL. Use --platform to bind URL/deep-link opens to the target platform. For iOS simulator initial stdout/stderr, put --launch-console <path> on this open command, for example agent-device open "Agent Device Tester" --platform ios --launch-console artifacts/launch-console.log. Expo Go/dev-client shells accept host + URL, for example agent-device open "Expo Go" exp://127.0.0.1:8081 --platform ios. macOS also supports --surface app|frontmost-app|desktop|menubar. --metro-host/--metro-port/--bundle-url/--launch-url set this session's Metro/debug runtime hints as part of open itself (applied to the app's dev-server prefs and recorded as the session's dev-server binding), so a fresh session has them before its first reload instead of needing a throwaway reload-first call just to seed hints; a later plain metro reload in the same session reuses whichever of these were set. A fresh open without these flags clears any leftover binding from a previous same-name session; close also clears it.`,summary:`Open an app, deep link or URL, save replays`,positionalArgs:[`appOrUrl?`,`url?`],allowedFlags:[`activity`,`launchConsole`,`launchArgs`,`deviceHub`,`testIme`,`saveScript`,`force`,`noRecord`,`relaunch`,`surface`,...wr,`launchUrl`]},To={positionalArgs:[`app?`],allowedFlags:[`saveScript`,`force`,`shutdown`]},Eo=(e,t)=>({...E(t),appsFilter:Ct(t.appsFilter)}),Do=(e,t)=>({...E(t),app:e[0],url:e[1],surface:t.surface,activity:t.activity,launchConsole:t.launchConsole,launchArgs:t.launchArgs,relaunch:t.relaunch,saveScript:t.saveScript,force:t.force,deviceHub:t.deviceHub,testIme:t.testIme,noRecord:t.noRecord,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,launchUrl:t.launchUrl}),Oo=(e,t)=>({...E(t),app:e[0],shutdown:t.shutdown,saveScript:t.saveScript,force:t.force}),ko=w(s.apps),Ao=w(s.open,Io),jo=w(s.close,e=>A(e.app)),Mo=P({name:`apps`,metadata:go,definition:yo,cliSchema:Co,cliReader:Eo,daemonWriter:ko,cliOutputFormatter:Z.apps}),No=P({name:`open`,metadata:_o,definition:bo,cliSchema:wo,cliReader:Do,daemonWriter:Ao,cliOutputFormatter:Z.open}),Po=P({name:`close`,metadata:vo,definition:So,cliSchema:To,cliReader:Oo,daemonWriter:jo,cliOutputFormatter:Z.close});function Fo(e){let{app:t,...n}=e;return n}function Io(e){return e.app?e.url?[e.app,e.url]:[e.app]:[]}const Lo=H(`devices`,`List available devices.`,{}),Ro=H(`capabilities`,`List commands supported by the selected device.`,{}),zo=H(`boot`,`Boot or prepare a selected device without using CLI positional arguments.`,{headless:h(`Boot without showing simulator UI when supported.`)}),Bo=H(`shutdown`,`Shutdown a selected simulator or emulator.`,{}),Vo=R(Lo,(e,t)=>e.devices.list(t)),Ho=R(Ro,(e,t)=>e.devices.capabilities(t)),Uo=R(zo,(e,t)=>e.devices.boot(t)),Wo=R(Bo,(e,t)=>e.devices.shutdown(t)),Go={summary:`Boot target device/simulator`,allowedFlags:[`headless`]},Ko={summary:`List supported commands for the selected device`,helpDescription:`List command names supported by the selected session device or explicit --platform/--device/--udid/--serial target.`},qo={summary:`Shutdown target simulator/emulator`},Jo=(e,t)=>E(t),Yo=(e,t)=>({...E(t),headless:t.headless}),Xo=w(s.devices),Zo=w(s.capabilities),Qo=w(s.boot),$o=w(s.shutdown),es=[P({name:`devices`,metadata:Lo,definition:Vo,cliReader:Jo,daemonWriter:Xo,cliOutputFormatter:Z.devices}),P({name:`capabilities`,metadata:Ro,definition:Ho,cliSchema:Ko,cliReader:Jo,daemonWriter:Zo,cliOutputFormatter:Z.capabilities}),P({name:`boot`,metadata:zo,definition:Uo,cliSchema:Go,cliReader:Yo,daemonWriter:Qo,cliOutputFormatter:Z.boot}),P({name:`shutdown`,metadata:Bo,definition:Wo,cliSchema:qo,cliReader:Jo,daemonWriter:$o,cliOutputFormatter:Z.shutdown})],ts=H(`doctor`,`Diagnose device, app, Metro, and React Native setup/readiness issues.`,{targetApp:f(`Installed app package/bundle id or app name to verify without opening a session.`),remote:h(`Check remote connection setup instead of local device inventory.`)}),ns=P({name:`doctor`,metadata:ts,definition:R(ts,(e,t)=>e.command.doctor(t)),cliSchema:{usageOverride:`doctor [--platform ios|android|vega|macos|linux|web|apple] [--app <id-or-name>] [--remote]`,helpDescription:`Setup and recovery diagnostic for device, app, dev-server, and RN/Expo readiness issues. Reports local device inventory, active sessions, optional app discovery, scoped toolchain info, and Metro reachability inferred from cwd/runtime. On iOS simulators it also warms the XCTest runner build cache in the background when missing. Pass --app to verify a target app on the one matching booted device without opening a session. Use --remote to check remote connection setup without probing local devices. Default output is compact; use --json for full checks and evidence.`,summary:`Diagnose device, app, dev-server, and RN/Expo readiness`,allowedFlags:[`targetApp`,`remote`]},cliReader:(e,t)=>({...E(t),targetApp:t.targetApp,remote:t.remote}),daemonWriter:w(s.doctor),cliOutputFormatter:Z.doctor});function rs(t,n=`--github-actions-artifact`){let r=t.indexOf(`:`);if(r<=0||r===t.length-1)throw new e(`INVALID_ARGS`,`${n} must use owner/repo:artifact, for example thymikee/RNCLI83:6635342232`);let{owner:i,repo:a}=os(t.slice(0,r),n);return as(i,a,t.slice(r+1),`${n} artifact`)}function is(t,n){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`${n} installSource must be an object.`);let r=t;if(cs(r.type,`${n} installSource.type`)!==`github-actions-artifact`)throw new e(`INVALID_ARGS`,`${n} installSource.type must be "github-actions-artifact".`);let{owner:i,repo:a}=os(cs(r.repo,`${n} installSource.repo`),`${n} installSource.repo`);return as(i,a,r.artifact,`${n} installSource.artifact`)}function as(e,t,n,r){return typeof n==`number`||us(n)?{kind:`github-actions-artifact`,owner:e,repo:t,artifactId:ls(n,r)}:{kind:`github-actions-artifact`,owner:e,repo:t,artifactName:cs(n,r)}}function os(t,n){let r=t.indexOf(`/`);if(r<=0||r===t.length-1||t.indexOf(`/`,r+1)!==-1)throw new e(`INVALID_ARGS`,`${n} must use owner/repo.`);let i={owner:t.slice(0,r).trim(),repo:t.slice(r+1).trim()};if(!i.owner||!i.repo)throw new e(`INVALID_ARGS`,`${n} must use owner/repo.`);return i}function ss(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function cs(t,n){let r=ss(t);if(!r)throw new e(`INVALID_ARGS`,`${n} must be a non-empty string.`);return r}function ls(t,n){let r=typeof t==`number`?t:typeof t==`string`?Number(t):NaN;if(!Number.isInteger(r))throw new e(`INVALID_ARGS`,`${n} must be an integer.`);return r}function us(e){return typeof e==`string`&&/^\d+$/.test(e.trim())}const ds=H(`install`,`Install an app binary.`,{app:f(`Optional app identifier hint.`),appPath:d(f(`Path to app binary.`))}),fs=H(`reinstall`,`Reinstall an app binary.`,{app:d(f()),appPath:d(f(`Path to app binary.`))}),ps=H(`install-from-source`,`Install an app from a structured source.`,{source:d(_(qt(`Install source object.`))),retainPaths:h(),retentionMs:m()}),ms=R(ds,(e,t)=>e.apps.install(t)),hs=R(fs,(e,t)=>e.apps.reinstall(t)),gs=R(ps,(e,t)=>e.apps.installFromSource(t)),_s={usageOverride:`install <path> | install <app> <path>`,listUsageOverride:`install <path>`,positionalArgs:[`appOrPath`,`path?`]},vs={positionalArgs:[`app`,`path`]},ys={usageOverride:`install-from-source <url> | install-from-source --github-actions-artifact <owner/repo:artifact>`,listUsageOverride:`install-from-source`,helpDescription:`Install app builds from URLs, remote source specs, or CI artifacts resolved by a remote daemon.`,summary:`Install app builds from URLs, remote source specs, or CI artifacts`,positionalArgs:[`url?`],allowedFlags:[`header`,`githubActionsArtifact`,`installSource`,`retainPaths`,`retentionMs`]},bs=(e,t)=>Es(e,t),xs=(e,t)=>Ds(e,t),Ss=(e,t)=>({...E(t),source:As(e,t),retainPaths:t.retainPaths,retentionMs:t.retentionMs}),Cs=w(s.install,e=>Os(e.app,e.appPath)),ws=w(s.reinstall,e=>ks(e.app,e.appPath)),Ts=[P({name:`install`,metadata:ds,definition:ms,cliSchema:_s,cliReader:bs,daemonWriter:Cs,cliOutputFormatter:Z.install}),P({name:`reinstall`,metadata:fs,definition:hs,cliSchema:vs,cliReader:xs,daemonWriter:ws,cliOutputFormatter:Z.reinstall}),P({name:`install-from-source`,metadata:ps,definition:gs,cliSchema:ys,cliReader:Ss,daemonWriter:e=>T(ae.installSource,[],{...e,installSource:e.source,retainMaterializedPaths:e.retainPaths,materializedPathRetentionMs:e.retentionMs}),cliOutputFormatter:Z[`install-from-source`]})];function Es(e,t){let[n,r]=e,i=r!==void 0;return{...E(t),...i?{app:M(n,`install requires app`)}:{},appPath:M(i?r:n,`install requires path`)}}function Ds(e,t){return{...E(t),app:M(e[0],`reinstall requires app`),appPath:M(e[1],`reinstall requires path`)}}function Os(e,t){let n=N(t,`missing app path`);return typeof e==`string`&&e.length>0?[e,n]:[n]}function ks(e,t){return[N(e,`missing first positional`),N(t,`missing second positional`)]}function As(t,n){let r=t[0]?.trim();if(t.length>1)throw new e(`INVALID_ARGS`,`install-from-source accepts either one <url> positional or --github-actions-artifact`);let i=n.githubActionsArtifact?rs(n.githubActionsArtifact):void 0,a=n.installSource;if(+!!r+ +!!i+ +!!a!=1)throw new e(`INVALID_ARGS`,`install-from-source requires exactly one source: <url>, --github-actions-artifact, or config installSource`);if(!r&&n.header&&n.header.length>0)throw new e(`INVALID_ARGS`,`install-from-source --header is only supported for URL sources`);return i||a||{kind:`url`,url:r,headers:js(n.header)}}function js(t){if(!t||t.length===0)return;let n={};for(let r of t){let t=r.indexOf(`:`);if(t<=0)throw new e(`INVALID_ARGS`,`Invalid --header value "${r}". Expected "name:value".`);let i=r.slice(0,t).trim(),a=r.slice(t+1).trim();if(!i)throw new e(`INVALID_ARGS`,`Invalid --header value "${r}". Header name cannot be empty.`);n[i]=a}return n}const Ms=H(`prepare`,`Prepare platform helper infrastructure.`,{action:d(g([`ios-runner`])),timeoutMs:m(`Maximum wall-clock time for the prepare command.`)}),Ns=P({name:`prepare`,metadata:Ms,definition:R(Ms,(e,t)=>e.command.prepare(t)),cliSchema:{usageOverride:`prepare ios-runner --platform ios|macos [--timeout <ms>]`,listUsageOverride:`prepare`,helpDescription:`Prepare platform helper infrastructure. ios-runner builds/reuses, starts, and health-checks the XCTest runner so later Apple snapshots and interactions do not pay first-use startup cost. In JSON output, top-level buildMs/connectMs/healthCheckMs are diagnostic fields and may overlap; use timing.additiveParts for additive wall-clock phase totals. In CI, run it after boot/install and before replay/test; if replay/test starts a separate daemon, stop the prepare daemon before replay/test so it does not keep the prepared runner lease. It is not a recovery step for "runner already owned by another agent-device daemon"; stop the owning daemon on the Mac with simulator access instead. Runner build/start output is written to the session runner.log; daemon.log is for daemon lifecycle/startup issues.`,summary:`Pre-warm platform helpers, especially the iOS/macOS XCTest runner before Apple automation`,positionalArgs:[`ios-runner`],allowedFlags:[`timeoutMs`]},cliReader:(e,t)=>({...E(t),action:M(e[0],`prepare requires subcommand`),timeoutMs:t.timeoutMs}),daemonWriter:w(s.prepare,e=>[N(e.action,`prepare requires subcommand`)]),cliOutputFormatter:Z.prepare}),Ps=H(`push`,`Deliver a push payload.`,{app:d(f()),payload:d(_({oneOf:[u(),qt()]}))}),Fs=H(`trigger-app-event`,`Trigger an app-defined event.`,{event:d(f()),payload:qs()}),Is=R(Ps,(e,t)=>e.apps.push(t)),Ls=R(Fs,(e,t)=>e.apps.triggerEvent(t)),Rs={listUsageOverride:`push`,helpDescription:`Deliver push notification payloads to an installed app.`,summary:`Deliver push notification payloads to an installed app`,positionalArgs:[`bundleOrPackage`,`payloadOrJson`]},zs={usageOverride:`trigger-app-event <event> [payloadJson]`,listUsageOverride:`trigger-app-event`,helpDescription:`Invoke app-defined automation or test events with an optional structured payload.`,summary:`Invoke app-defined automation/test events with optional structured payloads`,positionalArgs:[`event`,`payloadJson?`]},Bs=(e,t)=>({...E(t),app:M(e[0],`push requires bundleOrPackage`),payload:M(e[1],`push requires payloadOrJson`)}),Vs=(e,t)=>({...E(t),event:M(e[0],`trigger-app-event requires event`),payload:e[1]?qn(e[1],`trigger-app-event payload`):void 0}),Hs=w(s.push,e=>Gs(e)),Us=w(s.triggerAppEvent,e=>Ks(e)),Ws=[P({name:`push`,metadata:Ps,definition:Is,cliSchema:Rs,cliReader:Bs,daemonWriter:Hs}),P({name:`trigger-app-event`,metadata:Fs,definition:Ls,cliSchema:zs,cliReader:Vs,daemonWriter:Us})];function Gs(e){return[e.app,typeof e.payload==`string`?e.payload:JSON.stringify(e.payload)]}function Ks(e){return[e.event,...e.payload?[JSON.stringify(e.payload)]:[]]}function qs(){return Jt()}const Js=H(`session`,`List active sessions or print daemon state directory.`,{action:g([`list`,`state-dir`,`save-script`],`list shows active sessions; state-dir prints the daemon state directory; save-script publishes an armed recording without teardown.`),path:f(`Optional .ad output path for save-script.`),force:h(`Atomically replace an existing save-script target.`)}),Ys=P({name:`session`,metadata:Js,definition:R(Js,async(e,{action:t,path:n,force:r,...i})=>{let a=t??`list`;return Zs(a,n,r),a===`state-dir`?{stateDir:await e.sessions.stateDir(i)}:a===`save-script`?await e.sessions.saveScript({...i,path:n,force:r}):{sessions:await e.sessions.list(i)}}),cliSchema:{usageOverride:`session list | session state-dir | session save-script [path] [--force]`,listUsageOverride:`session`,helpDescription:`List active sessions, print the effective daemon state directory, or publish an armed open-to-destination script without closing its session`,positionalArgs:[`list|state-dir|save-script?`,`path?`],allowedFlags:[`force`]},cliReader:(e,t)=>({...E(t),action:Xs(e[0]),path:e[1],force:t.force}),cliOutputFormatter:Z.session});function Xs(t){let n=t??`list`;if(n===`list`||n===`state-dir`||n===`save-script`)return n;throw new e(`INVALID_ARGS`,`session only supports list, state-dir, or save-script`)}function Zs(t,n,r){if(t!==`save-script`&&!(n===void 0&&r!==!0))throw new e(`INVALID_ARGS`,`session ${t} does not accept a path or --force; use session save-script [path] [--force] to publish a recording.`)}const Qs=H(`viewport`,`Resize the active web viewport.`,{width:d(m(`Viewport width in CSS pixels.`,{min:1})),height:d(m(`Viewport height in CSS pixels.`,{min:1}))}),$s=P({name:`viewport`,metadata:Qs,definition:R(Qs,(e,t)=>e.command.viewport(t)),cliSchema:{helpDescription:`Resize the active web viewport before taking snapshots or screenshots. Useful for fixed-layout or 100vh apps where changing the viewport reveals different content.`,summary:`Resize the active web viewport for the current session`,positionalArgs:[`width`,`height`]},cliReader:(e,t)=>({...E(t),width:Se(e[0],`width`),height:Se(e[1],`height`)}),daemonWriter:w(s.viewport,e=>{let{width:t,height:n}=e;return[String(t),String(n)]}),cliOutputFormatter:Z.viewport}),ec=F({name:`management`,commands:[...es,po,ns,Ns,Mo,Ys,No,Po,$s,...Ts,...Ws]});function tc(e){return{data:e.result,text:e.action===`reload`?`Reloaded React Native apps via ${e.result.reloadUrl}`:JSON.stringify(e.result,null,2)}}const nc={metro:({input:e,result:t})=>tc({result:t,action:e.action})},rc=[`auto`,`react-native`,`expo`,`repack`];function ic(t){if(t!==void 0){if(rc.includes(t))return t;throw new e(`INVALID_ARGS`,`metro prepare --kind must be auto, react-native, expo, or repack`)}}const ac=`metro`,oc=H(ac,`Prepare React Native dev-server runtime or reload apps.`,{action:d(g([`prepare`,`reload`])),projectRoot:f(),kind:_(u()),publicBaseUrl:f(),proxyBaseUrl:f(),bearerToken:f(),bridgeScope:_({type:`object`,additionalProperties:!0}),launchUrl:f(),port:m(),listenHost:f(),statusHost:f(),startupTimeoutMs:m(),probeTimeoutMs:m(),reuseExisting:h(),installDependenciesIfNeeded:h(),runtimeFilePath:f(),logPath:f(),metroHost:f(),metroPort:m(),bundleUrl:f(),timeoutMs:m()}),sc=F({name:`metro`,commands:[P({name:ac,metadata:oc,definition:R(oc,async(e,t)=>t.action===`prepare`?await e.metro.prepare(cc(t)):await e.metro.reload(uc(t))),cliSchema:{usageOverride:`metro prepare (--public-base-url <url> | --proxy-base-url <url>) [--project-root <path>] [--port <port>] [--kind auto|react-native|expo|repack]
|
|
15
|
-
agent-device metro reload [--metro-host <host>] [--metro-port <port>] [--bundle-url <url>]`,listUsageOverride:`metro`,
|
|
16
|
-
`),stderr:
|
|
17
|
-
`),stderr:
|
|
18
|
-
`)}function
|
|
19
|
-
`):void 0}function
|
|
20
|
-
`)||void 0}const
|
|
21
|
-
`)}function
|
|
22
|
-
`)}function
|
|
14
|
+
`)}}function yo(e){return`source`in e&&e.source===`daemon`}function bo(e){return B(dt(e))}function xo(e){return B(wt(e))}function So(e){let t=e,n=t.platform??`unknown`;return{data:t,text:`Boot ready: ${t.device??t.id??`unknown`} (${n})`}}function Co(e){let t=e,n=t.platform??`unknown`,r=t.device??t.id??`unknown`,i=t.shutdown;return{data:t,text:`${i&&typeof i==`object`&&`success`in i&&i.success===!0?`Shutdown`:`Shutdown failed`}: ${r} (${n})`}}function wo(e){let t=e,n=[`Doctor: ${typeof t.status==`string`?t.status:`unknown`}`],r=ko(t.checks);if(uo()){let e=typeof t.summary==`string`?t.summary:void 0;e&&n.push(e)}else if(r.length===0){let e=typeof t.summary==`string`?t.summary:`No blockers found.`;n.push(e)}else for(let e of r)n.push(Ct(e)),n.push(...bt(e));return{data:t,text:n.join(`
|
|
15
|
+
`)}}const Z={boot:R(So),shutdown:R(Co),devices:R(fo),capabilities:R(po),doctor:R(wo),apps:({input:e,result:t})=>mo({result:t,appsFilter:e.appsFilter}),session:R(ho),artifacts:R(vo),open:R(go),close:R(_o),install:R(bo),reinstall:R(bo),"install-from-source":R(xo),prepare:z,viewport:z};function To(e){let t=e.kind?` ${e.kind}`:``,n=e.target?` target=${e.target}`:``,r=typeof e.booted==`boolean`?` booted=${e.booted}`:``;return`${e.name} (${e.platform}${t}${n})${r}`}function Eo(e){let t=e.url?` ${e.url}`:``,n=e.availability?` ${e.availability}`:``;return`${e.kind}: ${e.name}${n}${t}`}function Do(e){let t=e.artifactType?` (${e.artifactType})`:``;return`${e.filename}${t}: ${e.mimeType} ${e.sizeBytes} bytes id=${e.id}`}function Oo(e){if(e.providerSessionId)return`agent-device artifacts ${e.providerSessionId} --provider ${e.provider} --json`}function ko(e){return Array.isArray(e)?e.filter(e=>!!e&&typeof e==`object`&&!Array.isArray(e)):[]}const Ao=V(`artifacts`,`List daemon or cloud provider artifacts for an active or completed session.`,{provider:p(`Cloud provider name, for example browserstack or aws-device-farm.`),providerSessionId:p(`Cloud provider session id or ARN.`)}),jo=N({name:`artifacts`,text:{summary:`List daemon or cloud provider session artifacts`},metadata:Ao,definition:L(Ao,(e,t)=>e.sessions.artifacts(t)),cliSchema:{usageOverride:`artifacts [provider-session-id] [--provider <name>]`,positionalArgs:[`provider-session-id?`],allowedFlags:[`provider`,`providerSessionId`]},cliReader:(e,t)=>({...E(t),provider:t.provider,providerSessionId:e[0]??t.providerSessionId}),daemonWriter:w(u.artifacts),cliOutputFormatter:Z.artifacts});function Mo(e){let{metroHost:t,metroPort:n,bundleUrl:r,launchUrl:i}=e;if(!(t===void 0&&n===void 0&&r===void 0&&i===void 0))return{metroHost:t,metroPort:n,bundleUrl:r,launchUrl:i}}function No(e){let{metroHost:t,metroPort:n,bundleUrl:r,launchUrl:i,...a}=e,o=Mo({metroHost:t,metroPort:n,bundleUrl:r,launchUrl:i});return o?{...a,runtime:o}:a}const Po=V(`apps`,`List the apps installed on the selected device. Include system or OEM apps only when they are needed as automation targets.`,{appsFilter:_([`user-installed`,`all`],`Restrict the listing to user-installed apps, or include system and OEM apps.`)}),Fo=V(`open`,`Boot the selected device when needed, then open an app, deep link, or URL in a session. Use the app or URL inputs to choose what becomes the foreground automation target.`,{app:p(`App name, bundle id, package, or URL.`),url:p(`Optional URL passed with an app shell.`),surface:_(st,`macOS presentation surface to open: the app itself, the frontmost app, the desktop, or the menu bar.`),activity:p(`Android activity name.`),launchConsole:p(`Launch console mode.`),launchArgs:on(`Launch arguments forwarded verbatim to the platform launch command.`),relaunch:g(`Force relaunch.`),saveScript:v({oneOf:[en(),d()]}),force:g(`Overwrite an existing --save-script target instead of refusing (alias: --overwrite).`),deviceHub:g(`Use Xcode Device Hub when surfacing Apple simulators.`),testIme:g(`Activate the headless Android test IME for deterministic Unicode text entry (default on for emulators; opt-in on real devices).`),noRecord:g(`Do not record this action.`),metroHost:p(`Session-scoped Metro/debug host hint applied to the opened app.`),metroPort:h(`Session-scoped Metro/debug port hint applied to the opened app. On an emulator/simulator the host defaults to the loopback alias (Android 10.0.2.2, iOS 127.0.0.1) when --metro-host is omitted; physical devices still require an explicit --metro-host.`,{min:1,max:65535}),bundleUrl:p(`Session-scoped bundle URL hint applied to the opened app.`),launchUrl:p(`Session-scoped launch URL hint applied to the opened app.`)}),Io=V(`close`,`Close the named app, or close the active session app when app is omitted. Use shutdown only when the selected simulator or emulator should also stop.`,{app:p(`Optional app to close.`),shutdown:g(`Shutdown the session/device where supported.`),saveScript:v({oneOf:[en(),d()]}),force:g(`Overwrite an existing --save-script target instead of refusing (alias: --overwrite).`)}),Lo=L(Po,(e,t)=>e.apps.list(t)),Ro=L(Fo,(e,t)=>e.apps.open(zo(t)));function zo(e){return No(e)}const Bo=L(Io,(e,t)=>t.app?e.apps.close(t):e.sessions.close($o(t))),Vo={allowedFlags:[`appsFilter`],defaults:{appsFilter:Pt}},Ho={positionalArgs:[`appOrUrl?`,`url?`],allowedFlags:[`activity`,`launchConsole`,`launchArgs`,`deviceHub`,`testIme`,`saveScript`,`force`,`noRecord`,`relaunch`,`surface`,...Br,`launchUrl`]},Uo={positionalArgs:[`app?`],allowedFlags:[`saveScript`,`force`,`shutdown`]},Wo=(e,t)=>({...E(t),appsFilter:Mt(t.appsFilter)}),Go=(e,t)=>({...E(t),app:e[0],url:e[1],surface:t.surface,activity:t.activity,launchConsole:t.launchConsole,launchArgs:t.launchArgs,relaunch:t.relaunch,saveScript:t.saveScript,force:t.force,deviceHub:t.deviceHub,testIme:t.testIme,noRecord:t.noRecord,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,launchUrl:t.launchUrl}),Ko=(e,t)=>({...E(t),app:e[0],shutdown:t.shutdown,saveScript:t.saveScript,force:t.force}),qo=w(u.apps),Jo=w(u.open,es),Yo=w(u.close,e=>k(e.app)),Xo=N({name:`apps`,text:{summary:`List installed apps`,cliDetail:`Defaults to user-installed apps; use --all to include system/OEM apps.`},metadata:Po,definition:Lo,cliSchema:Vo,cliReader:Wo,daemonWriter:qo,cliOutputFormatter:Z.apps}),Zo=N({name:`open`,text:{summary:`Open an app, deep link or URL, save replays`,cliDetail:`Use --platform to bind URL/deep-link opens to the target platform. For iOS simulator initial stdout/stderr, put --launch-console <path> on this open command, for example agent-device open "Agent Device Tester" --platform ios --launch-console artifacts/launch-console.log. Expo Go/dev-client shells accept host + URL, for example agent-device open "Expo Go" exp://127.0.0.1:8081 --platform ios. macOS also supports --surface app|frontmost-app|desktop|menubar. --metro-host/--metro-port/--bundle-url/--launch-url set this session's Metro/debug runtime hints as part of open itself (applied to the app's dev-server prefs and recorded as the session's dev-server binding), so a fresh session has them before its first reload instead of needing a throwaway reload-first call just to seed hints; a later plain metro reload in the same session reuses whichever of these were set. A fresh open without these flags clears any leftover binding from a previous same-name session; close also clears it.`,mcpDetail:`Metro and debug runtime hints given here are recorded as the session's dev-server binding, so a later reload reuses them; a fresh open without them clears any binding left by a previous same-name session.`},metadata:Fo,definition:Ro,cliSchema:Ho,cliReader:Go,daemonWriter:Jo,cliOutputFormatter:Z.open}),Qo=N({name:`close`,text:{summary:`Close an app or end the session`},metadata:Io,definition:Bo,cliSchema:Uo,cliReader:Ko,daemonWriter:Yo,cliOutputFormatter:Z.close});function $o(e){let{app:t,...n}=e;return n}function es(e){return e.app?e.url?[e.app,e.url]:[e.app]:[]}const ts=V(`devices`,`List available devices and simulators that can be selected for automation. Use platform, device, udid, or serial inputs on later commands to target one result.`,{}),ns=V(`capabilities`,`List the commands supported by the selected device or active session. Use device-selection inputs when checking support before a session is open.`,{}),rs=V(`boot`,`Boot or prepare the selected device or simulator so later commands can target it. The device is chosen through the device-selection inputs, not by naming it here.`,{headless:g(`Boot without showing simulator UI when supported.`)}),is=V(`shutdown`,`Shutdown a selected simulator or emulator.`,{}),as=L(ts,(e,t)=>e.devices.list(t)),os=L(ns,(e,t)=>e.devices.capabilities(t)),ss=L(rs,(e,t)=>e.devices.boot(t)),cs=L(is,(e,t)=>e.devices.shutdown(t)),ls={allowedFlags:[`headless`]},us={},ds={},fs={},ps=(e,t)=>E(t),ms=(e,t)=>({...E(t),headless:t.headless}),hs=w(u.devices),gs=w(u.capabilities),_s=w(u.boot),vs=w(u.shutdown),ys=[N({name:`devices`,text:{summary:`List available devices and simulators`},metadata:ts,definition:as,cliSchema:us,cliReader:ps,daemonWriter:hs,cliOutputFormatter:Z.devices}),N({name:`capabilities`,text:{summary:`List supported commands for the selected device`,cliDetail:`Select an explicit target with --platform/--device/--udid/--serial.`},metadata:ns,definition:os,cliSchema:ds,cliReader:ps,daemonWriter:gs,cliOutputFormatter:Z.capabilities}),N({name:`boot`,text:{summary:`Boot target device/simulator`},metadata:rs,definition:ss,cliSchema:ls,cliReader:ms,daemonWriter:_s,cliOutputFormatter:Z.boot}),N({name:`shutdown`,text:{summary:`Shutdown target simulator/emulator`},metadata:is,definition:cs,cliSchema:fs,cliReader:ps,daemonWriter:vs,cliOutputFormatter:Z.shutdown})],bs=V(`doctor`,`Diagnose device, app, development-server, and React Native or Expo readiness issues. Returns compact evidence for local inventory, sessions, optional app discovery, toolchains, and server reachability.`,{targetApp:p(`Installed app package/bundle id or app name to verify without opening a session.`),remote:g(`Check remote connection setup instead of local device inventory.`)}),xs=N({name:`doctor`,text:{summary:`Diagnose device, app, dev-server, and RN/Expo readiness`,cliDetail:`Metro reachability is inferred from cwd/runtime. On iOS simulators it also warms the XCTest runner build cache in the background when missing. Pass --app to verify a target app on the one matching booted device without opening a session. Use --remote to check remote connection setup without probing local devices. Default output is compact; use --json for full checks and evidence.`,mcpDetail:`On iOS simulators it also warms the XCTest runner build cache in the background when missing, so run it before the first Apple snapshot or interaction of a session.`},metadata:bs,definition:L(bs,(e,t)=>e.command.doctor(t)),cliSchema:{usageOverride:`doctor [--platform ios|android|vega|macos|linux|web|apple] [--app <id-or-name>] [--remote]`,allowedFlags:[`targetApp`,`remote`]},cliReader:(e,t)=>({...E(t),targetApp:t.targetApp,remote:t.remote}),daemonWriter:w(u.doctor),cliOutputFormatter:Z.doctor});function Ss(t,n=`--github-actions-artifact`){let r=t.indexOf(`:`);if(r<=0||r===t.length-1)throw new e(`INVALID_ARGS`,`${n} must use owner/repo:artifact, for example thymikee/RNCLI83:6635342232`);let{owner:i,repo:a}=Ts(t.slice(0,r),n);return ws(i,a,t.slice(r+1),`${n} artifact`)}function Cs(t,n){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`${n} installSource must be an object.`);let r=t;if(Ds(r.type,`${n} installSource.type`)!==`github-actions-artifact`)throw new e(`INVALID_ARGS`,`${n} installSource.type must be "github-actions-artifact".`);let{owner:i,repo:a}=Ts(Ds(r.repo,`${n} installSource.repo`),`${n} installSource.repo`);return ws(i,a,r.artifact,`${n} installSource.artifact`)}function ws(e,t,n,r){return typeof n==`number`||ks(n)?{kind:`github-actions-artifact`,owner:e,repo:t,artifactId:Os(n,r)}:{kind:`github-actions-artifact`,owner:e,repo:t,artifactName:Ds(n,r)}}function Ts(t,n){let r=t.indexOf(`/`);if(r<=0||r===t.length-1||t.indexOf(`/`,r+1)!==-1)throw new e(`INVALID_ARGS`,`${n} must use owner/repo.`);let i={owner:t.slice(0,r).trim(),repo:t.slice(r+1).trim()};if(!i.owner||!i.repo)throw new e(`INVALID_ARGS`,`${n} must use owner/repo.`);return i}function Es(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function Ds(t,n){let r=Es(t);if(!r)throw new e(`INVALID_ARGS`,`${n} must be a non-empty string.`);return r}function Os(t,n){let r=typeof t==`number`?t:typeof t==`string`?Number(t):NaN;if(!Number.isInteger(r))throw new e(`INVALID_ARGS`,`${n} must be an integer.`);return r}function ks(e){return typeof e==`string`&&/^\d+$/.test(e.trim())}const As=V(`install`,`Install an app binary from a local path. Provide an app identifier with the path when the target needs explicit app selection; use reinstall to replace an already installed app.`,{app:p(`Optional app identifier hint.`),appPath:f(p(`Path to app binary.`))}),js=V(`reinstall`,`Replace an installed app with a binary from a local path. Use this when preserving the same app identity while installing a new build on the selected device.`,{app:f(p()),appPath:f(p(`Path to app binary.`))}),Ms=V(`install-from-source`,`Install app builds from URLs, remote source specs, or CI artifacts resolved by a remote daemon.`,{source:f(v(nn(`Install source object.`))),retainPaths:g(),retentionMs:h()}),Ns=L(As,(e,t)=>e.apps.install(t)),Ps=L(js,(e,t)=>e.apps.reinstall(t)),Fs=L(Ms,(e,t)=>e.apps.installFromSource(t)),Is={usageOverride:`install <path> | install <app> <path>`,listUsageOverride:`install <path>`,positionalArgs:[`appOrPath`,`path?`]},Ls={positionalArgs:[`app`,`path`]},Rs={usageOverride:`install-from-source <url> | install-from-source --github-actions-artifact <owner/repo:artifact>`,listUsageOverride:`install-from-source`,positionalArgs:[`url?`],allowedFlags:[`header`,`githubActionsArtifact`,`installSource`,`retainPaths`,`retentionMs`]},zs=(e,t)=>Gs(e,t),Bs=(e,t)=>Ks(e,t),Vs=(e,t)=>({...E(t),source:Ys(e,t),retainPaths:t.retainPaths,retentionMs:t.retentionMs}),Hs=w(u.install,e=>qs(e.app,e.appPath)),Us=w(u.reinstall,e=>Js(e.app,e.appPath)),Ws=[N({name:`install`,text:{summary:`Install an app binary from a path`},metadata:As,definition:Ns,cliSchema:Is,cliReader:zs,daemonWriter:Hs,cliOutputFormatter:Z.install}),N({name:`reinstall`,text:{summary:`Replace an installed app with a new build`},metadata:js,definition:Ps,cliSchema:Ls,cliReader:Bs,daemonWriter:Us,cliOutputFormatter:Z.reinstall}),N({name:`install-from-source`,text:{summary:`Install app builds from URLs or CI artifacts`},metadata:Ms,definition:Fs,cliSchema:Rs,cliReader:Vs,daemonWriter:e=>T(et.installSource,[],{...e,installSource:e.source,retainMaterializedPaths:e.retainPaths,materializedPathRetentionMs:e.retentionMs}),cliOutputFormatter:Z[`install-from-source`]})];function Gs(e,t){let[n,r]=e,i=r!==void 0;return{...E(t),...i?{app:j(n,`install requires app`)}:{},appPath:j(i?r:n,`install requires path`)}}function Ks(e,t){return{...E(t),app:j(e[0],`reinstall requires app`),appPath:j(e[1],`reinstall requires path`)}}function qs(e,t){let n=M(t,`missing app path`);return typeof e==`string`&&e.length>0?[e,n]:[n]}function Js(e,t){return[M(e,`missing first positional`),M(t,`missing second positional`)]}function Ys(t,n){let r=t[0]?.trim();if(t.length>1)throw new e(`INVALID_ARGS`,`install-from-source accepts either one <url> positional or --github-actions-artifact`);let i=n.githubActionsArtifact?Ss(n.githubActionsArtifact):void 0,a=n.installSource;if(+!!r+ +!!i+ +!!a!=1)throw new e(`INVALID_ARGS`,`install-from-source requires exactly one source: <url>, --github-actions-artifact, or config installSource`);if(!r&&n.header&&n.header.length>0)throw new e(`INVALID_ARGS`,`install-from-source --header is only supported for URL sources`);return i||a||{kind:`url`,url:r,headers:Xs(n.header)}}function Xs(t){if(!t||t.length===0)return;let n={};for(let r of t){let t=r.indexOf(`:`);if(t<=0)throw new e(`INVALID_ARGS`,`Invalid --header value "${r}". Expected "name:value".`);let i=r.slice(0,t).trim(),a=r.slice(t+1).trim();if(!i)throw new e(`INVALID_ARGS`,`Invalid --header value "${r}". Header name cannot be empty.`);n[i]=a}return n}const Zs=V(`prepare`,`Prepare platform helper infrastructure. ios-runner builds/reuses, starts, and health-checks the XCTest runner so later Apple snapshots and interactions do not pay first-use startup cost. In JSON output, top-level buildMs/connectMs/healthCheckMs are diagnostic fields and may overlap; use timing.additiveParts for additive wall-clock phase totals. In CI, run it after boot/install and before replay/test; if replay/test starts a separate daemon, stop the prepare daemon before replay/test so it does not keep the prepared runner lease. It is not a recovery step for "runner already owned by another agent-device daemon"; stop the owning daemon on the Mac with simulator access instead. Runner build/start output is written to the session runner.log; daemon.log is for daemon lifecycle/startup issues.`,{action:f(_([`ios-runner`])),timeoutMs:h(`Maximum wall-clock time for the prepare command.`)}),Qs=N({name:`prepare`,text:{summary:`Pre-warm platform helpers before automation`},metadata:Zs,definition:L(Zs,(e,t)=>e.command.prepare(t)),cliSchema:{usageOverride:`prepare ios-runner --platform ios|macos [--timeout <ms>]`,listUsageOverride:`prepare`,positionalArgs:[`ios-runner`],allowedFlags:[`timeoutMs`]},cliReader:(e,t)=>({...E(t),action:j(e[0],`prepare requires subcommand`),timeoutMs:t.timeoutMs}),daemonWriter:w(u.prepare,e=>[M(e.action,`prepare requires subcommand`)]),cliOutputFormatter:Z.prepare}),$s=V(`push`,`Deliver push notification payloads to an installed app.`,{app:f(p()),payload:f(v({oneOf:[d(),nn()]}))}),ec=V(`trigger-app-event`,`Ask the app to handle an app-defined automation or test event, with an optional structured payload. Call this only for event names and payload shapes the app documents.`,{event:f(p(`Name of an app-defined automation or test event the app documents.`)),payload:fc(`Structured payload passed to the event, in the shape the app documents for it.`)}),tc=L($s,(e,t)=>e.apps.push(t)),nc=L(ec,(e,t)=>e.apps.triggerEvent(t)),rc={listUsageOverride:`push`,positionalArgs:[`bundleOrPackage`,`payloadOrJson`]},ic={usageOverride:`trigger-app-event <event> [payloadJson]`,listUsageOverride:`trigger-app-event`,positionalArgs:[`event`,`payloadJson?`]},ac=(e,t)=>({...E(t),app:j(e[0],`push requires bundleOrPackage`),payload:j(e[1],`push requires payloadOrJson`)}),oc=(e,t)=>({...E(t),event:j(e[0],`trigger-app-event requires event`),payload:e[1]?rr(e[1],`trigger-app-event payload`):void 0}),sc=w(u.push,e=>uc(e)),cc=w(u.triggerAppEvent,e=>dc(e)),lc=[N({name:`push`,text:{summary:`Deliver a push notification payload`},metadata:$s,definition:tc,cliSchema:rc,cliReader:ac,daemonWriter:sc}),N({name:`trigger-app-event`,text:{summary:`Invoke an app-defined automation event`},metadata:ec,definition:nc,cliSchema:ic,cliReader:oc,daemonWriter:cc})];function uc(e){return[e.app,typeof e.payload==`string`?e.payload:JSON.stringify(e.payload)]}function dc(e){return[e.event,...e.payload?[JSON.stringify(e.payload)]:[]]}function fc(e){return an(e)}const pc=V(`session`,`List active sessions, print the effective daemon state directory, or publish an armed open-to-destination script without closing its session`,{action:_([`list`,`state-dir`,`save-script`],`list shows active sessions; state-dir prints the daemon state directory; save-script publishes an armed recording without teardown.`),path:p(`Optional .ad output path for save-script.`),force:g(`Atomically replace an existing save-script target.`)}),mc=N({name:`session`,text:{summary:`List sessions, show the state dir, or publish a script`},metadata:pc,definition:L(pc,async(e,{action:t,path:n,force:r,...i})=>{let a=t??`list`;return gc(a,n,r),a===`state-dir`?{stateDir:await e.sessions.stateDir(i)}:a===`save-script`?await e.sessions.saveScript({...i,path:n,force:r}):{sessions:await e.sessions.list(i)}}),cliSchema:{usageOverride:`session list | session state-dir | session save-script [path] [--force]`,listUsageOverride:`session`,positionalArgs:[`list|state-dir|save-script?`,`path?`],allowedFlags:[`force`]},cliReader:(e,t)=>({...E(t),action:hc(e[0]),path:e[1],force:t.force}),cliOutputFormatter:Z.session});function hc(t){let n=t??`list`;if(n===`list`||n===`state-dir`||n===`save-script`)return n;throw new e(`INVALID_ARGS`,`session only supports list, state-dir, or save-script`)}function gc(t,n,r){if(t!==`save-script`&&!(n===void 0&&r!==!0))throw new e(`INVALID_ARGS`,`session ${t} does not accept a path or --force; use session save-script [path] [--force] to publish a recording.`)}const _c=V(`viewport`,`Resize the active web viewport before taking snapshots or screenshots. Useful for fixed-layout or 100vh apps where changing the viewport reveals different content.`,{width:f(h(`Viewport width in CSS pixels.`,{min:1})),height:f(h(`Viewport height in CSS pixels.`,{min:1}))}),vc=N({name:`viewport`,text:{summary:`Resize the active web viewport for the current session`},metadata:_c,definition:L(_c,(e,t)=>e.command.viewport(t)),cliSchema:{positionalArgs:[`width`,`height`]},cliReader:(e,t)=>({...E(t),width:Tt(e[0],`width`),height:Tt(e[1],`height`)}),daemonWriter:w(u.viewport,e=>{let{width:t,height:n}=e;return[String(t),String(n)]}),cliOutputFormatter:Z.viewport}),yc=P({name:`management`,commands:[...ys,jo,xs,Qs,Xo,mc,Zo,Qo,vc,...Ws,...lc]});function bc(e){return{data:e.result,text:e.action===`reload`?`Reloaded React Native apps via ${e.result.reloadUrl}`:JSON.stringify(e.result,null,2)}}const xc={metro:({input:e,result:t})=>bc({result:t,action:e.action})},Sc=[`auto`,`react-native`,`expo`,`repack`];function Cc(t){if(t!==void 0){if(Sc.includes(t))return t;throw new e(`INVALID_ARGS`,`metro prepare --kind must be auto, react-native, expo, or repack`)}}const wc=`metro`,Tc=V(wc,`Prepare a React Native development server or ask connected apps to reload, using the development server this session is bound to. Provide explicit runtime inputs only to override that binding for one call.`,{action:f(_([`prepare`,`reload`])),projectRoot:p(),kind:v(d()),publicBaseUrl:p(),proxyBaseUrl:p(),bearerToken:p(),bridgeScope:v({type:`object`,additionalProperties:!0}),launchUrl:p(),port:h(),listenHost:p(),statusHost:p(),startupTimeoutMs:h(),probeTimeoutMs:h(),reuseExisting:g(),installDependenciesIfNeeded:g(),runtimeFilePath:p(),logPath:p(),metroHost:p(),metroPort:h(),bundleUrl:p(),timeoutMs:h()}),Ec=P({name:`metro`,commands:[N({name:wc,text:{summary:`Prepare the dev server or reload apps`,cliDetail:`reload with no --metro-host/--metro-port/--bundle-url resolves against the dev server this session last bound via metro prepare or open's metro hint flags (falling back to localhost:8081 only when the session never bound one), so it never silently reloads a different project's server on the default port; pass an explicit flag to override the session hint for one call. The reload URL keeps the bound bundle URL mount prefix instead of collapsing to the host root, and when the server has no HTTP /reload route (Expo) the reload is broadcast over its /message websocket instead of trusting the app-page fallback. The binding is cleared when the session closes, and a fresh open without hint flags also clears any leftover binding from a previous same-name session. --kind expo (detected or forced) requests the virtual-entry bundle URL (.expo/.virtual-metro-entry.bundle) instead of index.bundle, since index.bundle 404s/500s against Expo dev servers in monorepos. Dependency install auto-detects the package manager from the nearest yarn.lock/pnpm-lock.yaml/bun.lock/bun.lockb/package-lock.json walking up from --project-root (bounded at the repo root), so Yarn/pnpm workspace monorepos with the lockfile at the repo root do not wrongly fall back to npm install (which fails on workspace: dependency specifiers); if install still fails, pass --no-install-deps when dependencies are already installed (for example via a monorepo root install).`,mcpDetail:`The binding is cleared when the session closes, and a fresh open without runtime hints also clears any leftover binding from a previous same-name session.`},metadata:Tc,definition:L(Tc,async(e,t)=>t.action===`prepare`?await e.metro.prepare(Dc(t)):await e.metro.reload(kc(t))),cliSchema:{usageOverride:`metro prepare (--public-base-url <url> | --proxy-base-url <url>) [--project-root <path>] [--port <port>] [--kind auto|react-native|expo|repack]
|
|
16
|
+
agent-device metro reload [--metro-host <host>] [--metro-port <port>] [--bundle-url <url>]`,listUsageOverride:`metro`,positionalArgs:[`prepare|reload`],allowedFlags:[...Br,...zr]},cliReader:(t,n)=>{let r=(t[0]??``).toLowerCase();if(r!==`prepare`&&r!==`reload`)throw new e(`INVALID_ARGS`,`metro requires a subcommand: prepare or reload`);if(r===`reload`)return{action:r,metroHost:n.metroHost,metroPort:n.metroPort,bundleUrl:n.bundleUrl,timeoutMs:n.metroProbeTimeoutMs};if(!n.metroPublicBaseUrl&&!n.metroProxyBaseUrl)throw new e(`INVALID_ARGS`,`metro prepare requires --public-base-url <url> or --proxy-base-url <url>.`);return{action:r,projectRoot:n.metroProjectRoot,kind:Cc(n.kind??n.metroKind),port:n.metroPreparePort,listenHost:n.metroListenHost,statusHost:n.metroStatusHost,publicBaseUrl:n.metroPublicBaseUrl,proxyBaseUrl:n.metroProxyBaseUrl,bearerToken:n.metroBearerToken,bridgeScope:n.tenant&&n.runId&&n.leaseId?{tenantId:n.tenant,runId:n.runId,leaseId:n.leaseId}:void 0,startupTimeoutMs:n.metroStartupTimeoutMs,probeTimeoutMs:n.metroProbeTimeoutMs,reuseExisting:n.metroNoReuseExisting?!1:void 0,installDependenciesIfNeeded:n.metroNoInstallDeps?!1:void 0,runtimeFilePath:n.metroRuntimeFile}},cliOutputFormatter:xc.metro})]});function Dc(e){return{projectRoot:e.projectRoot,kind:e.kind,publicBaseUrl:e.publicBaseUrl,proxyBaseUrl:e.proxyBaseUrl,bearerToken:e.bearerToken,bridgeScope:e.bridgeScope??Oc(e),port:e.port,listenHost:e.listenHost,statusHost:e.statusHost,startupTimeoutMs:e.startupTimeoutMs,probeTimeoutMs:e.probeTimeoutMs,reuseExisting:e.reuseExisting,installDependenciesIfNeeded:e.installDependenciesIfNeeded,runtimeFilePath:e.runtimeFilePath}}function Oc(e){return e.tenant&&e.runId&&e.leaseId?{tenantId:e.tenant,runId:e.runId,leaseId:e.leaseId}:void 0}function kc(e){return{metroHost:e.metroHost,metroPort:e.metroPort,bundleUrl:e.bundleUrl,timeoutMs:e.timeoutMs}}function Ac(e,t){return e.includes(t)}function jc(t,n,r={}){let i=n===void 0?void 0:r.normalize?.(n)??n;if(i!==void 0&&Ac(t,i))return i;throw new e(`INVALID_ARGS`,(typeof r.message==`function`?r.message(n):r.message)??`Invalid value: ${n}. Use ${t.join(`|`)}.`)}const Mc=[`started`,`stopped`,`marked`,`cleared`,`restarted`,`removedRotatedFiles`];function Nc(e){return{data:e,text:e.path,stderr:sl([al(e,[`active`,`state`,`backend`,`sizeBytes`]),Zc(e),e.hint,ol(e.notes)])}}function Pc(e){let t=e.events??[];return{data:e,text:t.length>0?Rc(t):`No session events found.`,stderr:sl([al(e,[`path`,`cursor`,`nextCursor`,`limit`])])}}function Fc(e){let t=[],n=e.entries??[];if(e.path&&t.push(e.path),n.length===0)t.push(`No recent HTTP(s) entries found.`);else for(let e of n)t.push(...nl(e));return{data:e,text:t.join(`
|
|
17
|
+
`),stderr:sl([al(e,[`active`,`state`,`backend`,`include`,`scannedLines`,`matchedLines`]),ol(e.notes)])}}function Ic(e){return{data:e,text:[`Audio probe: ${String(e.state??`stopped`)} heard=${String(e.heard===!0)}`,Xc(`rmsDbfs`,e.rmsDbfs),Xc(`peakDbfs`,e.peakDbfs)].filter(e=>!!e).join(`
|
|
18
|
+
`),stderr:sl([al(e,[`active`,`backend`,`source`,`durationMs`,`elapsedMs`,`bucketMs`,`sampleCount`,`sourceCount`,`mediaElementCount`]),ol(e.notes)])}}const Lc={logs:R(Nc),events:R(Pc),network:R(Fc),audio:R(Ic)};function Rc(e){let t=e.map(zc),n=Math.min(Math.max(...t.map(e=>e.label.length),5),32);return t.map(e=>Bc(e,n)).join(`
|
|
19
|
+
`)}function zc(e){return{timestamp:Vc(e.ts),label:Hc(e),summary:Uc(e)}}function Bc(e,t){let n=e.label.padEnd(t),r=e.timestamp?`${e.timestamp} ${n}`:n.trimEnd();return e.summary?`${r} ${e.summary}`:r.trimEnd()}function Vc(e){return e?e.replace(`T`,` `):``}function Hc(e){let t=e.command??`command`;switch(e.kind){case`request.started`:return`start ${t}`;case`request.finished`:return $c([e.status===`error`?`error`:`ok`,t,Yc(tl(e.details?.durationMs))]);case`action.recorded`:return`action ${t}`;default:return $c([e.kind??`event`,e.command])}}function Uc(e){let t=Wc(e.summary,e);return`${t}${Gc(e,t)}`.trim()}function Wc(e,t){let n=e?.trim()??``,r=t.command??``;return t.kind===`request.started`&&n===`Started ${r}`||t.kind===`request.finished`&&n===`Finished ${r}`?``:n}function Gc(e,t){if(e.kind!==`action.recorded`)return``;let n=e.details;if(!n)return``;let r=[Kc(n,t),Jc(tl(n.textLength))].filter(e=>!!e);return r.length>0?` (${r.join(`, `)})`:``}function Kc(e,t){let n=el(e.ref)??el(e.selector)??qc(e);if(!(!n||t.includes(n)))return`target=${n}`}function qc(e){let t=tl(e.x),n=tl(e.y);return t===void 0||n===void 0?void 0:`(${t}, ${n})`}function Jc(e){return e===void 0?void 0:`text=${e} chars`}function Yc(e){return e===void 0?void 0:`${Math.round(e)}ms`}function Xc(e,t){if(!Array.isArray(t))return;let n=t.filter(e=>typeof e==`number`&&Number.isFinite(e));return n.length>0?`${e}: [${n.join(`, `)}]`:void 0}function Zc(e){return Mc.map(t=>Qc(t,e[t])).filter(Boolean).join(` `)||void 0}function Qc(e,t){return t==null?``:`${e}=${t}`}function $c(e){return e.filter(e=>!!e).join(` `)}function el(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function tl(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function nl(e){let t=e.method??`HTTP`,n=e.url??`<unknown-url>`,r=e.status===void 0?``:` status=${e.status}`,i=[`${e.timestamp?`${e.timestamp} `:``}${t} ${n}${r}${e.durationMs===void 0?``:` durationMs=${e.durationMs}`}`];return e.headers?il(i,`headers`,e.headers):(rl(i,`request headers`,e.requestHeaders),rl(i,`response headers`,e.responseHeaders)),il(i,`request`,e.requestBody),il(i,`response`,e.responseBody),i}function rl(e,t,n){!n||Object.keys(n).length===0||e.push(` ${t}: ${JSON.stringify(n)}`)}function il(e,t,n){n!==void 0&&e.push(` ${t}: ${n}`)}function al(e,t){return t.map(t=>e[t]!==void 0&&e[t]!==null?`${t}=${e[t]}`:``).filter(Boolean).join(` `)||void 0}function ol(e){let t=e?.filter(e=>e.length>0)??[];return t.length>0?t.join(`
|
|
20
|
+
`):void 0}function sl(e){return e.filter(e=>!!e).join(`
|
|
21
|
+
`)||void 0}const cl=`logs`,ll=`events`,ul=`network`,dl=`audio`,fl=[`dump`,`log`],pl=[`probe`],ml=[`start`,`status`,`stop`],hl=V(cl,`Session app log info, start/stop streaming, diagnostics, and markers`,{action:_(Xe),message:p(),restart:g()}),gl=V(ll,`Read the daemon-owned session event timeline as paged JSON-friendly entries`,{limit:h(),cursor:p()}),_l=V(ul,`Dump recent HTTP(s) traffic parsed from the session app log`,{action:_(fl),limit:h(),include:_(n)}),vl=V(dl,`Measure browser or host-rendered simulator/emulator audio as compact dBFS buckets. Start a probe before requesting its status or stopping it.`,{action:_(pl),probeAction:_(ml),durationMs:h(`Probe duration in milliseconds.`),bucketMs:h(`Audio level bucket size in milliseconds.`)}),yl=L(hl,(e,t)=>e.observability.logs(t)),bl=L(gl,(e,t)=>e.observability.events(t)),xl=L(_l,(e,t)=>e.observability.network(t)),Sl=L(vl,(e,t)=>e.observability.audio(t)),Cl=P({name:`observability`,commands:[N({name:cl,text:{summary:`Manage session app logs`},metadata:hl,definition:yl,cliSchema:{usageOverride:`logs path | logs start | logs stop | logs clear [--restart] | logs doctor | logs mark [message...]`,positionalArgs:[`path|start|stop|clear|doctor|mark`,`message?`],allowsExtraPositionals:!0,allowedFlags:[`restart`]},cliReader:(e,t)=>({...E(t),action:Ol(e[0]),message:e.slice(1).join(` `)||void 0,restart:t.restart}),daemonWriter:w(cl,e=>wl(e)),cliOutputFormatter:Lc.logs}),N({name:ll,text:{summary:`Read session event timeline`},metadata:gl,definition:bl,cliSchema:{usageOverride:`events [limit] [cursor]`,listUsageOverride:`events`,positionalArgs:[`limit?`,`cursor?`]},cliReader:(e,t)=>({...E(t),limit:e[0]?.trim()?sr(e[0]):void 0,cursor:e[1]}),daemonWriter:e=>T(ll,Tl(e),e),cliOutputFormatter:Lc.events}),N({name:ul,text:{summary:`Inspect HTTP(S) traffic from session logs`},metadata:_l,definition:xl,cliSchema:{usageOverride:`network dump [limit] [summary|headers|body|all] [--include summary|headers|body|all] | network log [limit] [summary|headers|body|all] [--include summary|headers|body|all]`,listUsageOverride:`network`,positionalArgs:[`dump|log`,`limit?`,`include?`],allowedFlags:[`networkInclude`]},cliReader:(e,t)=>({...E(t),action:kl(e[0]),limit:sr(e[1]),include:t.networkInclude??Al(e[2])}),daemonWriter:e=>T(ul,El(e),{...e,networkInclude:e.include}),cliOutputFormatter:Lc.network}),N({name:dl,text:{summary:`Probe audio levels`},metadata:vl,definition:Sl,cliSchema:{usageOverride:`audio probe start [durationSeconds] [bucketMs] | audio probe status | audio probe stop`,listUsageOverride:`audio`,positionalArgs:[`probe`,`start|status|stop`,`durationSeconds?`,`bucketMs?`]},cliReader:(e,t)=>({...E(t),action:jl(e[0]),probeAction:Ml(e[1]),durationMs:Nl(e[2]),bucketMs:sr(e[3])}),daemonWriter:e=>T(dl,Dl(e),e),cliOutputFormatter:Lc.audio})]});function wl(e){return[e.action??`path`,...k(e.message)]}function Tl(e){return e.cursor===void 0?A(e.limit):[e.limit===void 0?``:String(e.limit),e.cursor]}function El(e){return[...e.action?[e.action]:[],...A(e.limit)]}function Dl(e){return[e.action??`probe`,e.probeAction??`status`,...A(e.durationMs),...A(e.bucketMs)]}function Ol(e){if(e!==void 0)return jc(Xe,e,{message:`logs requires path, start, stop, doctor, mark, or clear`})}function kl(t){if(t!==void 0){if(t===`dump`||t===`log`)return t;throw new e(`INVALID_ARGS`,`network requires dump or log`)}}function Al(e){if(e!==void 0)return jc(n,e,{message:`network include must be summary, headers, body, or all`})}function jl(e){if(e!==void 0)return jc(pl,e,{message:`audio requires probe`})}function Ml(e){if(e!==void 0)return jc(ml,e,{message:`audio probe requires start, status, or stop`})}function Nl(e){let t=sr(e);return t===void 0?void 0:Math.round(t*1e3)}function Pl(e){let t=e;return{data:t,text:Il(t)}}const Fl={perf:R(Pl)};function Il(e){let t=Bl(e);if(t)return t;let n=l(e.artifact)?e.artifact:void 0;return n?zl(n):Ll(l(e.metrics)?e.metrics:void 0)}function Ll(e){let t=l(e?.fps)?e.fps:void 0,n=ru(e);if(!t)return Xl(n,`missing frame metric`);if(t.available===!1)return Xl(n,Zl(t));let r=Ql(t);return r?Rl(t,r):Xl(n,`missing dropped-frame summary`)}function Rl(e,t){let n=[`Frame health: ${t}`],r=tu(e);return r.length>0&&n.push(`Worst windows:`,...r),n.join(`
|
|
22
|
+
`)}function zl(e){let t=typeof e.kind==`string`?e.kind:`memory`;if(e.available===!1)return`Memory artifact (${t}): unavailable - ${typeof e.reason==`string`&&e.reason.length>0?e.reason:`not available`}`;let n=typeof e.path==`string`?e.path:void 0,r=Q(e.sizeBytes),i=r===void 0?``:` (${lu(r)})`;return n?`Memory artifact (${t}): ${n}${i}`:`Memory artifact (${t}): captured${i}`}function Bl(e){return e.kind===`xctrace`?Vl(e):Wl(e)}function Vl(e){let t=typeof e.perf==`string`?e.perf:void 0,n=Hl(e);if(!(!t||!n||e.kind!==`xctrace`))return Ul(n,typeof e.mode==`string`?e.mode:`capture`,t,e.template)}function Hl(e){return typeof e.outPath==`string`?e.outPath:typeof e.reportPath==`string`?e.reportPath:void 0}function Ul(e,t,n,r){let i=[e,`Perf ${t}: ${n}`];return typeof r==`string`&&i.push(`Template: ${r}`),i.join(`
|
|
23
|
+
`)}function Wl(e){let t=Gl(e);if(t)return`Perf ${t.action}: ${t.kind} ${t.type}${Kl(e)}${ql(e)}${Yl(e)}`}function Gl(e){let t=Jl(e.action),n=Jl(e.kind),r=Jl(e.type);return t&&n&&r?{action:t,kind:n,type:r}:void 0}function Kl(e){let t=Jl(e.state);return t?` state=${t}`:``}function ql(e){let t=Jl(e.outPath);if(!t)return``;let n=Q(e.sizeBytes);return`\n${t}${n===void 0?``:` (${lu(n)})`}`}function Jl(e){return typeof e==`string`?e:void 0}function Yl(e){let t=l(e.summary)?e.summary:void 0,n=l(t?.frameHealth)?t.frameHealth:void 0;if(!n||n.available!==!0)return``;let r=Q(n.droppedFramePercent),i=Q(n.droppedFrameCount),a=Q(n.totalFrameCount);return r===void 0||i===void 0||a===void 0?``:`\nTrace frame health: dropped ${ou(r)} (${Math.round(i)}/${Math.round(a)} frames)`}function Xl(e,t){return e?`Performance: ${e}`:`Frame health: unavailable - ${t}`}function Zl(e){return typeof e.reason==`string`&&e.reason.length>0?e.reason:`not available`}function Ql(e){let t=Q(e.droppedFramePercent),n=Q(e.droppedFrameCount);if(!(t===void 0||n===void 0))return[`dropped ${ou(t)}`,$l(n,Q(e.totalFrameCount)),eu(Q(e.sampleWindowMs))].filter(Boolean).join(` `)}function $l(e,t){return t===void 0?`(${Math.round(e)} dropped frames)`:`(${Math.round(e)}/${Math.round(t)} frames)`}function eu(e){return e===void 0?``:`window ${su(e)}`}function tu(e){return Array.isArray(e.worstWindows)?e.worstWindows.flatMap(e=>{if(!l(e))return[];let t=nu(e);return t?[t]:[]}):[]}function nu(e){let t=Q(e.startOffsetMs),n=Q(e.endOffsetMs),r=Q(e.missedDeadlineFrameCount);if(t===void 0||n===void 0||r===void 0)return;let i=Q(e.worstFrameMs),a=i===void 0?``:`, worst ${su(i)}`;return`- +${su(t)}-+${su(n)}: ${Math.round(r)} missed-deadline frames${a}`}function ru(e){let t=l(e?.cpu)?e.cpu:void 0,n=l(e?.memory)?e.memory:void 0,r=[iu(t),au(n)].filter(e=>!!e);return r.length>0?r.join(`, `):void 0}function iu(e){if(e?.available!==!0)return;let t=Q(e.usagePercent);return t===void 0?void 0:`CPU ${ou(t)}`}function au(e){if(e?.available!==!0)return;let t=Q(e.residentMemoryKb)??Q(e.totalPssKb)??Q(e.totalRssKb);return t===void 0?void 0:`memory ${cu(t)}`}function Q(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function ou(e){return`${Number.isInteger(e)?e:e.toFixed(1)}%`}function su(e){let t=Math.max(0,Math.round(e));if(t<1e3)return`${t}ms`;let n=Math.round(t/1e3);if(n<60)return`${n}s`;let r=Math.floor(n/60),i=n%60;return i>0?`${r}m ${i}s`:`${r}m`}function cu(e){let t=e/1024;return`${t>=10?Math.round(t):t.toFixed(1)}MB`}function lu(e){if(e<1024)return`${Math.round(e)}B`;let t=e/1024;if(t<1024)return`${t>=10?Math.round(t):t.toFixed(1)}KB`;let n=t/1024;return`${n>=10?Math.round(n):n.toFixed(1)}MB`}const uu=`perf`,du=V(uu,`Collect session performance metrics, frame health, memory diagnostics, and platform profiling artifacts. Prefer structured metrics for a first-pass diagnosis; raw profiles and traces remain session artifacts.`,{area:_(_t),subject:_(at),action:_(Ze),kind:_(gt),template:p(`xctrace template name, for example Time Profiler.`),out:p(`Output artifact path.`),tracePath:p(`Existing .trace path to report, defaults to the latest session trace.`)}),fu=P({name:`perf`,commands:[N({name:uu,text:{summary:`Check metrics, frames, memory, or profiles`,cliDetail:`Covers Apple xctrace and Android native Simpleperf/Perfetto artifacts. Prefer explicit perf metrics --json for first-pass startup/CPU/memory data. For CPU profiles, start/stop write the raw artifact and report writes a compact .json summary; include report after simpleperf stop when the task needs agent-readable native CPU evidence. Bare perf and metrics remain aliases. Native perf output is agent evidence: compact state, artifact path, and size only; raw profiles/traces stay on disk.`,mcpDetail:`For CPU profiles, start and stop write the raw artifact while report writes a compact summary; request the report when the task needs readable native CPU evidence. Profiling output is evidence only: compact state, artifact path, and size.`},metadata:du,definition:L(du,(e,t)=>e.observability.perf(t)),cliSchema:{usageOverride:`perf metrics --json
|
|
23
24
|
agent-device perf frames --json
|
|
24
25
|
agent-device perf memory sample --json
|
|
25
26
|
agent-device perf memory snapshot [--kind android-hprof|memgraph] [--out <path>]
|
|
@@ -30,9 +31,9 @@ import{_ as e,n as t,t as n}from"./sdk-contracts.js";import{$t as r,At as i,Dt a
|
|
|
30
31
|
agent-device perf cpu profile start --kind simpleperf --out <cpu.perf.data>
|
|
31
32
|
agent-device perf cpu profile stop --kind simpleperf
|
|
32
33
|
agent-device perf cpu profile report --kind simpleperf --out <cpu-report.json>
|
|
33
|
-
agent-device perf trace start|stop --kind perfetto [--out <path>]`,listUsageOverride:`perf`,
|
|
34
|
-
`)}}const
|
|
35
|
-
`)}function
|
|
36
|
-
`)}}return
|
|
34
|
+
agent-device perf trace start|stop --kind perfetto [--out <path>]`,listUsageOverride:`perf`,positionalArgs:[`area?`,`subjectOrAction?`,`action?`],allowedFlags:[`kind`,`perfTemplate`,`out`]},cliReader:(e,t)=>({...E(t),...hu(e,{kind:bu(t.kind),template:t.perfTemplate,out:t.out})}),daemonWriter:w(uu,e=>pu(e)),cliOutputFormatter:Fl.perf})]});function pu(e){let t=e.area??(e.action?`metrics`:void 0);return t===`cpu`?mu([...k(t),...k(e.subject),...k(e.action),...k(e.kind)],e):t===`trace`?mu([...k(t),...k(e.action),...k(e.kind)],e):[...k(t),...k(e.action)]}function mu(e,t){let n=[...e];return(t.template||t.out||t.tracePath)&&n.push(t.template??``),(t.out||t.tracePath)&&n.push(t.out??``),t.tracePath&&n.push(t.tracePath),n}function hu(e,t={}){if(e[0]!==void 0&&e[1]===void 0){let n=_u(e[0],{allowUndefined:!0});if(n)return{action:n,kind:yu(t.kind),out:t.out}}let n=gu(e[0]);return n===`cpu`?{area:n,subject:vu(e[1]),action:_u(e[2]),kind:yu(t.kind),template:t.template,out:t.out}:n===`trace`?{area:n,action:_u(e[1]),kind:yu(t.kind),template:t.template,out:t.out}:{area:n,action:_u(e[1]),kind:yu(t.kind),out:t.out}}function gu(t){if(t===void 0)return;let n=t.toLowerCase();if(tt(n))return n;throw new e(`INVALID_ARGS`,it)}function _u(t,n={}){if(t===void 0)return;let r=t.toLowerCase();if($e(r))return r;if(!n.allowUndefined)throw new e(`INVALID_ARGS`,Qe)}function vu(t){let n=t?.toLowerCase();if(n!==void 0&&kt(n))return n;throw new e(`INVALID_ARGS`,rt)}function yu(t){if(t===void 0)return;let n=t.toLowerCase();if(nt(n))return n;throw new e(`INVALID_ARGS`,Ye)}function bu(e){return typeof e==`string`?yu(e):void 0}const xu=`react-native`,Su=V(xu,`Run supported React Native automation helpers. Use dismiss-overlay to close a visible development error overlay before continuing normal UI automation.`,{action:f(_([`dismiss-overlay`]))}),Cu=P({name:`react-native`,commands:[N({name:xu,text:{summary:`Run React Native automation helpers`},metadata:Su,definition:L(Su,(e,t)=>e.command.reactNative(t)),cliSchema:{usageOverride:`react-native dismiss-overlay`,listUsageOverride:`react-native dismiss-overlay`,positionalArgs:[`dismiss-overlay`]},cliReader:(e,t)=>({...E(t),action:wu(e[0])}),daemonWriter:w(xu,e=>[M(e.action,`react-native requires action`)])})]});function wu(t){if(t===`dismiss-overlay`)return t;throw new e(`INVALID_ARGS`,`react-native supports only: dismiss-overlay`)}function Tu(e){let t=e,n=typeof t.outPath==`string`?t.outPath:``,r=Ou(t);if(r.length<=1)return{data:t,text:Du(t,n)};let i=[`Recording chunks:`];for(let e of r)i.push(` ${e.index}: ${e.path}`);return typeof t.telemetryPath==`string`&&i.push(`Telemetry: ${t.telemetryPath}`),typeof t.warning==`string`&&i.push(`Warning: ${t.warning}`),typeof t.overlayWarning==`string`&&i.push(`Overlay warning: ${t.overlayWarning}`),{data:t,text:i.join(`
|
|
35
|
+
`)}}const Eu={record:R(Tu)};function Du(e,t){let n=[];return t&&n.push(t),typeof e.sessionStateDir==`string`&&n.push(`Session state: ${e.sessionStateDir}`),typeof e.warning==`string`&&n.push(`Warning: ${e.warning}`),typeof e.overlayWarning==`string`&&n.push(`Overlay warning: ${e.overlayWarning}`),n.join(`
|
|
36
|
+
`)}function Ou(e){let t=e.chunks;return Array.isArray(t)?t.flatMap(e=>{if(!e||typeof e!=`object`)return[];let t=e;return typeof t.index!=`number`||typeof t.path!=`string`?[]:[{index:t.index,path:t.path}]}):[]}const ku=`record`,Au=`trace`,ju=[`start`,`stop`],Mu=V(ku,`Start or stop a screen recording for the active app session or, where supported, the selected device. Long Android recordings can return multiple video artifacts.`,{action:f(_(ju)),path:p(),fps:h(),maxSize:rn(se.migration.record),quality:_(ot),hideTouches:g(),recordingScope:_(ct)}),Nu=V(Au,`Start or stop trace-log capture and return the resulting artifact when capture ends. Use the same artifact path for the matching start and stop requests when an explicit path is required.`,{action:f(_(ju)),path:p()}),Pu=L(Mu,(e,t)=>e.recording.record(t)),Fu=L(Nu,(e,t)=>e.recording.trace(t)),Iu={usageOverride:`record start [path] [--scope <app|device|system>] [--fps <n>] [--quality <medium|high>] [--hide-touches] | record stop`,listUsageOverride:`record start [path] | record stop`,positionalArgs:[`start|stop`,`path?`],allowedFlags:[`recordingScope`,`fps`,`quality`,`hideTouches`]},Lu={usageOverride:`trace start <path> | trace stop <path>`,listUsageOverride:`trace start <path> | trace stop <path>`,positionalArgs:[`start|stop`,`path?`]},Ru=(e,t)=>({...E(t),action:Gu(e[0],ku),path:e[1],fps:t.fps,quality:t.quality,hideTouches:t.hideTouches,recordingScope:t.recordingScope}),zu=(e,t)=>({...E(t),action:Gu(e[0],Au),path:e[1]}),Bu=w(ku,e=>Wu(e)),Vu=e=>(ne(`record`,e),Bu(e)),Hu=w(Au,e=>Wu(e)),Uu=P({name:`recording`,commands:[N({name:ku,text:{summary:`Start or stop screen recording`,cliDetail:`The default --scope app requires an active app session from open <app>; use --scope device/system to explicitly request whole-screen recording where the selected backend supports it. Android record start publishes a durable device manifest, recordings longer than the 180s adb screenrecord limit are returned as multiple MP4 chunks while the daemon stays alive, and daemon-restart recovery uses only manifest-owned chunks. Use --quality to choose medium or high export quality.`},metadata:Mu,definition:Pu,cliSchema:Iu,cliReader:Ru,daemonWriter:Vu,cliOutputFormatter:Eu.record}),N({name:Au,text:{summary:`Start or stop trace capture`,cliDetail:`Pass that path as the same positional argument to start and stop.`},metadata:Nu,definition:Fu,cliSchema:Lu,cliReader:zu,daemonWriter:Hu})]});function Wu(e){return[e.action,...k(e.path)]}function Gu(t,n){if(t===`start`||t===`stop`)return t;throw new e(`INVALID_ARGS`,`${n} requires start|stop`)}const Ku=`replay`,qu=`test`,Ju=V(Ku,`Run a recorded automation script, including compatible Maestro YAML flows. A script without a terminal close leaves its session active for subsequent automation.`,{path:f(p()),update:g(),backend:p(),maestro:g(),env:on(),metroHost:p(`Metro/debug host hint inherited by replay-opened sessions.`),metroPort:h(`Metro/debug port hint inherited by replay-opened sessions.`),bundleUrl:p(`Bundle URL hint inherited by replay-opened sessions.`),resumeFrom:h(),resumePlanDigest:p(),keepSession:g(`Leave the session active by suppressing exactly an authored terminal close in native .ad.`),saveScript:v({oneOf:[en(),d()]}),force:g()}),Yu=V(qu,`Run one or more replay scripts as a serial test suite`,{paths:f(on()),update:g(),backend:p(),maestro:g(),env:on(),metroHost:p(`Metro/debug host hint inherited by each test session.`),metroPort:h(`Metro/debug port hint inherited by each test session.`),bundleUrl:p(`Bundle URL hint inherited by each test session.`),failFast:g(),timeoutMs:h(),retries:h(),recordVideo:g(),artifactsDir:p(),shardAll:h(),shardSplit:h()}),Xu=L(Ju,(e,t)=>e.replay.run(No(t))),Zu=L(Yu,(e,t)=>e.replay.test(No(t))),Qu={usageOverride:`replay <path> | replay export <file.ad> [--out <path>]`,positionalArgs:[`path`],allowsExtraPositionals:!0,allowedFlags:[`replayMaestro`,...Ur,...Br,`replayFrom`,`replayPlanDigest`,`replayKeepSession`,`timeoutMs`,`out`,`saveScript`,`force`],flagDescriptionOverrides:{saveScript:`Arm a repair transaction from this replay (ADR 0012): recording starts at step 1, and the healed script commits when the repair-armed session tears down (close, close --save-script, or idle-reap). Independent of the open/close authoring arm-on-open. Optional custom output path.`}},$u={usageOverride:`test <path-or-glob>...`,listUsageOverride:`test <path-or-glob>...`,positionalArgs:[`pathOrGlob`],allowsExtraPositionals:!0,allowedFlags:[`replayMaestro`,...Ur,...Br,`failFast`,`timeoutMs`,`retries`,`recordVideo`,`artifactsDir`,`reporter`,`reportJunit`,`shardAll`,`shardSplit`]},ed=P({name:`replay`,commands:[N({name:Ku,text:{summary:`Replay a recorded session or Maestro flow`,cliDetail:`For Maestro YAML compatibility flows, use replay <flow.yaml> --maestro and keep the target binding such as --platform ios on the replay command. A script with no terminal close leaves its session (and daemon) running until you close it or it idle-reaps — no different from a session opened interactively. For native .ad scripts, --keep-session suppresses exactly an authored terminal close so you can continue interactively.`},metadata:Ju,definition:Xu,cliSchema:Qu,cliReader:(e,t)=>({...E(t),path:j(e[0],`replay requires path`),update:t.replayUpdate,backend:t.replayMaestro?`maestro`:void 0,env:t.replayEnv,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,resumeFrom:t.replayFrom,resumePlanDigest:t.replayPlanDigest,keepSession:t.replayKeepSession,saveScript:t.saveScript,force:t.force}),daemonWriter:e=>T(Ku,[M(e.path,`replay requires path`)],{...e,replayUpdate:e.update,replayBackend:td(e),replayEnv:e.env,replayShellEnv:rd(process.env),replayFrom:e.resumeFrom,replayPlanDigest:e.resumePlanDigest,replayKeepSession:e.keepSession,saveScript:e.saveScript})}),N({name:qu,text:{summary:`Run replay test suites`},metadata:Yu,definition:Zu,cliSchema:$u,cliReader:(e,t)=>({...E(t),paths:e,update:t.replayUpdate,backend:t.replayMaestro?`maestro`:void 0,env:t.replayEnv,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,failFast:t.failFast,timeoutMs:t.timeoutMs,retries:t.retries,recordVideo:t.recordVideo,artifactsDir:t.artifactsDir,shardAll:t.shardAll,shardSplit:t.shardSplit}),daemonWriter:e=>T(qu,e.paths??[],{...nd(e),replayUpdate:e.update,replayBackend:td(e),replayEnv:e.env,replayShellEnv:rd(process.env)})})]});function td(e){return e.backend??(e.maestro===!0?`maestro`:void 0)}function nd(e){let t={...e};return delete t.reporter,delete t.reportJunit,t}function rd(e){let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&n.startsWith(`AD_VAR_`)&&(t[n]=r);return t}function id(e){return e}const ad={back:id({clientMethod:`back`,outputSchema:{type:`object`,properties:{action:{type:`string`,const:`back`},mode:{type:`string`,enum:be},message:{type:`string`}},required:[`action`,`mode`,`message`]}}),home:id({clientMethod:`home`,outputSchema:{type:`object`,properties:{action:{type:`string`,const:`home`},message:{type:`string`}},required:[`action`,`message`]}}),orientation:id({clientMethod:`orientation`,outputSchema:{type:`object`,properties:{action:{type:`string`,const:`orientation`},orientation:{type:`string`,enum:Nt},message:{type:`string`}},required:[`action`,`orientation`,`message`]}}),"app-switcher":id({clientMethod:`appSwitcher`,outputSchema:{type:`object`,properties:{action:{type:`string`,const:`app-switcher`},message:{type:`string`}},required:[`action`,`message`]}}),"tv-remote":id({clientMethod:`tvRemote`,outputSchema:{type:`object`,properties:{action:{type:`string`,const:`tv-remote`},button:{type:`string`,enum:pe},durationMs:{type:`number`},message:{type:`string`}},required:[`action`,`button`,`message`]}})};function od(e){return{data:e,text:ld(e)}}function sd(e){if(e.platform===`android`&&e.action===`status`){let t=[`Keyboard visible: ${e.visible===!0?`yes`:`no`}`,`Input type: ${e.type??e.inputType??`unknown`}`,`Input owner: ${e.inputOwner??`unknown`}`];return e.inputMethodPackage&&t.push(`Input method: ${e.inputMethodPackage}`),e.focusedPackage&&t.push(`Focused package: ${e.focusedPackage}`),e.focusedResourceId&&t.push(`Focused resource: ${e.focusedResourceId}`),t.push(`Next action: ${ud(e.visible,e.inputOwner)}`),{data:e,text:t.join(`
|
|
37
|
+
`)}}return B(e)}function cd(e){return e.action===`read`?{data:e,text:e.text}:B(e)}const $={appstate:R(od),back:pa,home:z,orientation:z,"app-switcher":z,keyboard:R(sd),clipboard:R(cd),"tv-remote":z};function ld(e){if(e.platform===`ios`){let t=[`Foreground app: ${e.appName??e.appBundleId??`unknown`}`];return e.appBundleId&&t.push(`Bundle: ${e.appBundleId}`),e.source&&t.push(`Source: ${e.source}`),t.join(`
|
|
37
38
|
`)}if(e.platform===`android`){let t=[`Foreground app: ${e.package??`unknown`}`];return e.activity&&t.push(`Activity: ${e.activity}`),t.join(`
|
|
38
|
-
`)}return null}function
|
|
39
|
+
`)}return null}function ud(e,t){return t===`ime`?`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`:e===!0?`Keyboard is visible and focused input appears app-owned; fill/type can proceed.`:`Keyboard is hidden; focus an app field before type, or use fill with a concrete target.`}const dd=`appstate`,fd=`back`,pd=`home`,md=`orientation`,hd=`app-switcher`,gd=`keyboard`,_d=`clipboard`,vd=`tv-remote`,yd=[`read`,`write`],bd=[`status`,`dismiss`],xd=V(dd,`Show foreground app/activity`,{}),Sd=V(fd,`Navigate back in the app or through system navigation. Use in-app for the app navigation stack and system when the platform back behavior is required.`,{mode:_(be),...W(fd)}),Cd=V(pd,`Send the selected device to its home screen. This leaves the app session open but moves the foreground away from the app.`,{}),wd=V(md,`Set device orientation on iOS and Android`,{orientation:f(_(Nt))}),Td=V(hd,`Open the device app switcher to inspect or change foreground apps. This changes the visible system UI and may move focus away from the current app.`,{}),Ed=V(gd,`Inspect Android keyboard visibility/type or press/dismiss the device keyboard. To hide the keyboard, use keyboard dismiss. It taps the keyboard dismiss/hide key when one is exposed, verifies the keyboard closed, and reports UNSUPPORTED_OPERATION when no dismiss key exists — background taps are never attempted.`,{action:_(bd)}),Dd=V(_d,`Read the current device clipboard text, or replace its contents with the given text.`,{action:f(_(yd)),text:p()}),Od=V(vd,`Press or long-press a TV remote or D-pad button on Android TV, tvOS, or Vega OS. Choose the button and optional hold duration through the input fields. The aliases ok, center, and enter all map to select.`,{button:f(_(pe)),durationMs:h(`Press duration in milliseconds. tvOS and Vega OS use the exact hold duration; Android TV maps any positive value to an ADB longpress (${a(`android`)}).`,{min:0})}),kd=L(xd,(e,t)=>e.command.appState(t)),Ad=L(Sd,(e,t)=>e.command.back(t),ad.back),jd=L(Cd,(e,t)=>e.command.home(t),ad.home),Md=L(wd,(e,t)=>e.command.orientation(t),ad.orientation),Nd=L(Td,(e,t)=>e.command.appSwitcher(t),ad[`app-switcher`]),Pd=L(Ed,(e,t)=>e.command.keyboard(t)),Fd=L(Dd,(e,t)=>e.command.clipboard(t)),Id=L(Od,(e,t)=>e.command.tvRemote(t),ad[`tv-remote`]),Ld={},Rd={usageOverride:`back [--in-app|--system] [--settle]`,allowedFlags:[`backMode`,...Bi(fd)]},zd={},Bd={},Vd={usageOverride:`orientation <portrait|portrait-upside-down|landscape-left|landscape-right>`,positionalArgs:[`orientation`]},Hd={usageOverride:`keyboard [status|get|dismiss|enter|return]`,positionalArgs:[`action?`]},Ud={usageOverride:`clipboard read | clipboard write <text>`,listUsageOverride:`clipboard read | clipboard write <text>`,positionalArgs:[`read|write`,`text?`],allowsExtraPositionals:!0},Wd={usageOverride:`tv-remote [press|longpress] ${Se} [--duration-ms <ms>]`,listUsageOverride:`tv-remote press|longpress <button> [--duration-ms <ms>]`,positionalArgs:[`press|longpress?`,`button`],allowedFlags:[`durationMs`]},Gd=(e,t)=>E(t),Kd=(e,t)=>E(t),qd=(e,t)=>E(t),Jd=(e,t)=>({...E(t),...Kn(t),mode:t.backMode}),Yd=(e,t)=>({...E(t),orientation:jt(e[0])}),Xd=(e,t)=>({...E(t),...ff(e)}),Zd=(e,t)=>({...E(t),...pf(e)}),Qd=(e,t)=>({...E(t),...mf(e,t.durationMs)}),$d=w(dd),ef=e=>T(fd,[],{...e,backMode:uf(e.mode)}),tf=w(pd),nf=w(md,e=>[M(e.orientation,`orientation requires orientation`)]),rf=w(hd),af=w(gd,e=>k(e.action)),of=w(_d,e=>df(e)),sf=w(vd,e=>[M(e.button,`tv-remote requires button`)]),cf=P({name:`system`,commands:[N({name:dd,text:{summary:`Show the foreground app and activity`},metadata:xd,definition:kd,clientMethod:`appState`,cliSchema:Ld,cliReader:Gd,daemonWriter:$d,cliOutputFormatter:$.appstate}),N({name:fd,text:{summary:`Navigate back in the app or system`},metadata:Sd,definition:Ad,cliSchema:Rd,cliReader:Jd,daemonWriter:ef,cliOutputFormatter:$.back}),N({name:pd,text:{summary:`Go to the device home screen`},metadata:Cd,definition:jd,cliSchema:zd,cliReader:Kd,daemonWriter:tf,cliOutputFormatter:$.home}),N({name:md,text:{summary:`Set device orientation`},metadata:wd,definition:Md,cliSchema:Vd,cliReader:Yd,daemonWriter:nf,cliOutputFormatter:$.orientation}),N({name:hd,text:{summary:`Open the device app switcher`},metadata:Td,definition:Nd,cliSchema:Bd,cliReader:qd,daemonWriter:rf,cliOutputFormatter:$[`app-switcher`]}),N({name:gd,text:{summary:`Inspect, press, or dismiss the device keyboard`},metadata:Ed,definition:Pd,clientMethod:`keyboard`,cliSchema:Hd,cliReader:Xd,daemonWriter:af,cliOutputFormatter:$.keyboard}),N({name:_d,text:{summary:`Read or write device clipboard text`},metadata:Dd,definition:Fd,clientMethod:`clipboard`,cliSchema:Ud,cliReader:Zd,daemonWriter:of,cliOutputFormatter:$.clipboard}),N({name:vd,text:{summary:`Press a TV remote/D-pad button`,cliDetail:`longpress holds for 500ms by default; --duration-ms overrides the preset.`},metadata:Od,definition:Id,cliSchema:Wd,cliReader:Qd,daemonWriter:sf,cliOutputFormatter:$[`tv-remote`]})]}),lf=fr(cf.definitions);function uf(e){return e===`in-app`||e===`system`?e:void 0}function df(e){return e.action===`read`?[`read`]:[`write`,e.text]}function ff(t){if(t.length>1)throw new e(`INVALID_ARGS`,`keyboard accepts at most one action argument.`);return S({action:hf(t[0])})}function pf(t){let n=t[0]?.toLowerCase();if(n!==`read`&&n!==`write`)throw new e(`INVALID_ARGS`,`clipboard requires a subcommand: read or write.`);if(n===`read`){if(t.length!==1)throw new e(`INVALID_ARGS`,`clipboard read does not accept additional arguments.`);return{action:n}}if(t.length<2)throw new e(`INVALID_ARGS`,`clipboard write requires text.`);return{action:n,text:t.slice(1).join(` `)}}function mf(t,n){let r=t[0]?.toLowerCase(),i=r===`press`||r===`longpress`?t.slice(1):t;if(i.length!==1)throw new e(`INVALID_ARGS`,`tv-remote requires exactly one button: ${pe.join(`, `)}.`);let a=n??(r===`longpress`?500:void 0);return S({button:oe(i[0]),durationMs:a})}function hf(t){let n=t?.toLowerCase();if(n===`get`)return`status`;if(n===void 0||n===`status`||n===`dismiss`||n===`enter`||n===`return`)return n;throw new e(`INVALID_ARGS`,`keyboard action must be status, get, dismiss, enter, or return.`)}const gf=[Ja,yc,Ai,cf,Cu,ed,Cl,fu,Ii,Uu,Ec,Ar];function _f(){return gf.flatMap(e=>[...e.metadata])}function vf(){return gf.flatMap(e=>[...e.definitions])}function yf(){return Cf(`cliSchemas`)}function bf(){return Cf(`cliReaders`)}function xf(){return Cf(`daemonWriters`)}function Sf(){return Cf(`cliOutputFormatters`)}function Cf(e){let t={};for(let n of gf){let r=n[e];if(r)for(let[n,i]of Object.entries(r)){if(Object.hasOwn(t,n))throw Error(`Duplicate ${String(e)} command family entry: ${n}`);t[n]=i}}return t}export{Vt as C,Kt as S,lr as _,vf as a,d as b,cf as c,lo as d,Wr as f,cr as g,Tr as h,xf as i,Cc as l,zr as m,bf as n,_f as o,Gr as p,yf as r,lf as s,Sf as t,Cs as u,en as v,Ht as w,Gt as x,nn as y};
|