agent-device 0.18.2 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.2.apk → agent-device-android-multitouch-helper-0.19.0.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.0.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.2.manifest.json → agent-device-android-multitouch-helper-0.19.0.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.2.apk → agent-device-android-snapshot-helper-0.19.0.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.0.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.2.manifest.json → agent-device-android-snapshot-helper-0.19.0.manifest.json} +6 -6
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +28 -0
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +9 -120
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +132 -66
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +155 -0
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +67 -0
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +20 -74
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +64 -0
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +0 -177
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +81 -48
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +102 -129
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +208 -46
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +82 -11
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +72 -0
- package/dist/src/agent-browser-tool.js +1 -0
- package/dist/src/android-adb.d.ts +64 -234
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android.js +1 -5
- package/dist/src/app-lifecycle.js +7 -0
- package/dist/src/apple-runner-options.js +1 -0
- package/dist/src/apps.js +5 -11
- package/dist/src/artifacts.d.ts +4 -3
- package/dist/src/artifacts.js +1 -1
- package/dist/src/audio-probe.js +1 -1
- package/dist/src/batch.d.ts +2 -177
- package/dist/src/batch.js +1 -1
- package/dist/src/cli-help.js +64 -38
- package/dist/src/cli-output.js +1 -1
- package/dist/src/cli-runner.js +2 -0
- package/dist/src/cli.js +12 -41
- package/dist/src/client-metro-companion.js +1 -0
- package/dist/src/client.js +3 -0
- package/dist/src/command-metadata.js +1 -0
- package/dist/src/command-schema.js +22 -0
- package/dist/src/command-surface.js +1 -1
- package/dist/src/contracts.d.ts +2 -213
- package/dist/src/contracts.js +1 -1
- package/dist/src/debug-symbols.js +5 -3
- package/dist/src/device-input-state.js +2 -0
- package/dist/src/device-rotation.js +14 -0
- package/dist/src/devices.js +1 -1
- package/dist/src/devices2.js +1 -0
- package/dist/src/devices3.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.d.ts +2 -81
- package/dist/src/finders.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/handler-utils.js +1 -1
- package/dist/src/helper.js +2 -0
- package/dist/src/host-process.js +2 -0
- package/dist/src/index.d.ts +1265 -1768
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +3 -1
- package/dist/src/input-actions2.js +1 -0
- package/dist/src/install-source.d.ts +13 -14
- package/dist/src/install-source.js +1 -1
- package/dist/src/install-source2.js +1 -0
- package/dist/src/interaction-snapshot.js +1 -0
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -1
- package/dist/src/internal/bin.d.ts +1 -1
- package/dist/src/internal/bin.js +2 -5
- package/dist/src/internal/companion-tunnel.d.ts +1 -1
- package/dist/src/internal/companion-tunnel.js +1 -1
- package/dist/src/internal/daemon.d.ts +1 -1
- package/dist/src/internal/daemon.js +16 -1
- package/dist/src/internal/png-worker.d.ts +29 -26
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/internal/update-check-entry.d.ts +1 -1
- package/dist/src/internal/update-check-entry.js +1 -1
- package/dist/src/io.d.ts +2 -85
- package/dist/src/io.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/logcat.js +6 -0
- package/dist/src/manifest.js +1 -0
- package/dist/src/metro.d.ts +70 -113
- package/dist/src/metro.js +1 -1
- package/dist/src/metro2.js +1 -0
- package/dist/src/notifications.js +1 -1
- package/dist/src/output-path.js +1 -0
- package/dist/src/path-resolution.js +1 -0
- package/dist/src/png-worker-contract.js +1 -0
- package/dist/src/points.js +4 -0
- package/dist/src/project-runtime.js +1 -0
- package/dist/src/provider.js +1 -1
- package/dist/src/providers.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +2 -5
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording-provider.js +1 -1
- package/dist/src/registry.js +37 -0
- package/dist/src/remote-config.d.ts +2 -83
- package/dist/src/reporting.js +9 -0
- package/dist/src/rolldown-runtime.js +1 -0
- package/dist/src/runner-client.js +1 -0
- package/dist/src/runner-provider.js +1 -0
- package/dist/src/runner-sequence.js +1 -1
- package/dist/src/runtime-transport.js +1 -0
- package/dist/src/runtime.js +3 -0
- package/dist/src/scoped-provider.js +1 -0
- package/dist/src/sdk-android-adb.d.ts +144 -0
- package/dist/src/sdk-android-adb.js +4 -0
- package/dist/src/sdk-app-inventory.d.ts +4 -0
- package/dist/src/sdk-app-inventory.js +1 -0
- package/dist/src/sdk-batch-runner.d.ts +40 -0
- package/dist/src/sdk-batch-runner.js +2 -0
- package/dist/src/sdk-batch.js +2 -0
- package/dist/src/sdk-contracts.d.ts +386 -0
- package/dist/src/sdk-contracts.js +2 -0
- package/dist/src/sdk-finders.d.ts +61 -0
- package/dist/src/sdk-finders.js +1 -0
- package/dist/src/sdk-io.d.ts +79 -0
- package/dist/src/sdk-io.js +1 -0
- package/dist/src/sdk-remote-config.d.ts +140 -0
- package/dist/src/sdk-remote-config.js +1 -0
- package/dist/src/sdk-selectors.js +1 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +39 -137
- package/dist/src/selectors.js +1 -1
- package/dist/src/selectors2.js +1 -0
- package/dist/src/server.js +3 -2
- package/dist/src/session.js +10 -11
- package/dist/src/setting-state.js +1 -0
- package/dist/src/simctl.js +1 -0
- package/dist/src/simulator.js +1 -2
- package/dist/src/snapshot-diagnostics.js +3 -0
- package/dist/src/snapshot-helper.js +5 -0
- package/dist/src/snapshot-quality.js +1 -0
- package/dist/src/snapshot.js +1 -2
- package/dist/src/snapshot2.js +2 -0
- package/dist/src/{5560.js → timeouts.js} +1 -1
- package/dist/src/tool-provider.js +3 -0
- package/dist/src/tool-provider2.js +1 -0
- package/dist/src/ttl-memo.js +1 -0
- package/dist/src/update-check.js +1 -0
- package/dist/src/url.js +1 -0
- package/dist/src/version.js +1 -0
- package/dist/src/web.js +1 -1
- package/dist/src/xml.js +2 -0
- package/package.json +12 -19
- package/server.json +2 -2
- package/skills/agent-device/SKILL.md +2 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.2.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.2.apk.sha256 +0 -1
- package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +0 -443
- package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -169
- package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +0 -220
- package/dist/src/1404.js +0 -1
- package/dist/src/1986.js +0 -1
- package/dist/src/2748.js +0 -1
- package/dist/src/2948.js +0 -30
- package/dist/src/3006.js +0 -1
- package/dist/src/314.js +0 -1
- package/dist/src/3340.js +0 -8
- package/dist/src/4418.js +0 -1
- package/dist/src/4428.js +0 -3
- package/dist/src/485.js +0 -1
- package/dist/src/4917.js +0 -1
- package/dist/src/495.js +0 -5
- package/dist/src/5448.js +0 -3
- package/dist/src/5484.js +0 -1
- package/dist/src/5643.js +0 -1
- package/dist/src/587.js +0 -1
- package/dist/src/5913.js +0 -4
- package/dist/src/6849.js +0 -1
- package/dist/src/6918.js +0 -1
- package/dist/src/6967.js +0 -1
- package/dist/src/760.js +0 -1
- package/dist/src/7871.js +0 -1
- package/dist/src/8184.js +0 -1
- package/dist/src/8225.js +0 -1
- package/dist/src/8391.js +0 -1
- package/dist/src/8404.js +0 -2
- package/dist/src/8414.js +0 -2
- package/dist/src/8875.js +0 -4
- package/dist/src/893.js +0 -1
- package/dist/src/8936.js +0 -1
- package/dist/src/9414.js +0 -1
- package/dist/src/9581.js +0 -22
- package/dist/src/9612.js +0 -1
- package/dist/src/9624.js +0 -1
- package/dist/src/9722.js +0 -38
- package/dist/src/devices~1.js +0 -1
- package/dist/src/devices~2.js +0 -1
- package/dist/src/input-actions~1.js +0 -1
- package/dist/src/rslib-runtime.js +0 -1
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { B as PlatformSelector, R as DeviceTarget, c as DaemonServerMode, l as DaemonTransportPreference, p as LeaseBackend, v as SessionIsolationMode, y as SessionRuntimeHints } from "./sdk-contracts.js";
|
|
2
|
+
|
|
3
|
+
//#region src/client/client-companion-tunnel-contract.d.ts
|
|
4
|
+
type CompanionTunnelScope = {
|
|
5
|
+
tenantId: string;
|
|
6
|
+
runId: string;
|
|
7
|
+
leaseId: string;
|
|
8
|
+
};
|
|
9
|
+
type MetroBridgeScope = CompanionTunnelScope;
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/metro/metro-types.d.ts
|
|
12
|
+
/** Re-export of {@link SessionRuntimeHints} under the Metro-specific alias used by public API consumers. */
|
|
13
|
+
type MetroRuntimeHints = SessionRuntimeHints;
|
|
14
|
+
type MetroBridgeResult = {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
baseUrl: string;
|
|
17
|
+
statusUrl: string;
|
|
18
|
+
bundleUrl: string;
|
|
19
|
+
iosRuntime: MetroRuntimeHints;
|
|
20
|
+
androidRuntime: MetroRuntimeHints;
|
|
21
|
+
upstream: {
|
|
22
|
+
bundleUrl: string;
|
|
23
|
+
host: string;
|
|
24
|
+
port: number;
|
|
25
|
+
statusUrl: string;
|
|
26
|
+
};
|
|
27
|
+
probe: {
|
|
28
|
+
reachable: boolean;
|
|
29
|
+
statusCode: number;
|
|
30
|
+
latencyMs: number;
|
|
31
|
+
detail: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
type MetroBridgeRuntimePayload = {
|
|
35
|
+
metro_host?: string;
|
|
36
|
+
metro_port?: number;
|
|
37
|
+
metro_bundle_url?: string;
|
|
38
|
+
launch_url?: string;
|
|
39
|
+
};
|
|
40
|
+
type MetroBridgeDescriptor = {
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
base_url: string;
|
|
43
|
+
status_url?: string;
|
|
44
|
+
bundle_url?: string;
|
|
45
|
+
ios_runtime: MetroBridgeRuntimePayload;
|
|
46
|
+
android_runtime: MetroBridgeRuntimePayload;
|
|
47
|
+
upstream: {
|
|
48
|
+
bundle_url?: string;
|
|
49
|
+
host?: string;
|
|
50
|
+
port?: number;
|
|
51
|
+
status_url?: string;
|
|
52
|
+
};
|
|
53
|
+
probe: {
|
|
54
|
+
reachable: boolean;
|
|
55
|
+
status_code: number;
|
|
56
|
+
latency_ms: number;
|
|
57
|
+
detail: string;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/metro/client-metro.d.ts
|
|
62
|
+
type MetroPrepareKind = 'auto' | 'react-native' | 'expo';
|
|
63
|
+
type ResolvedMetroKind = Exclude<MetroPrepareKind, 'auto'>;
|
|
64
|
+
type PrepareMetroRuntimeResult = {
|
|
65
|
+
projectRoot: string;
|
|
66
|
+
kind: ResolvedMetroKind;
|
|
67
|
+
dependenciesInstalled: boolean;
|
|
68
|
+
packageManager: string | null;
|
|
69
|
+
started: boolean;
|
|
70
|
+
reused: boolean;
|
|
71
|
+
pid: number;
|
|
72
|
+
logPath: string;
|
|
73
|
+
statusUrl: string;
|
|
74
|
+
runtimeFilePath: string | null;
|
|
75
|
+
iosRuntime: MetroRuntimeHints;
|
|
76
|
+
androidRuntime: MetroRuntimeHints;
|
|
77
|
+
bridge: MetroBridgeResult | null;
|
|
78
|
+
};
|
|
79
|
+
type ReloadMetroResult = {
|
|
80
|
+
reloaded: true;
|
|
81
|
+
reloadUrl: string;
|
|
82
|
+
status: number;
|
|
83
|
+
body: string;
|
|
84
|
+
};
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/remote/remote-config-schema.d.ts
|
|
87
|
+
type RemoteConfigMetroOptions = {
|
|
88
|
+
metroProjectRoot?: string;
|
|
89
|
+
metroKind?: MetroPrepareKind;
|
|
90
|
+
metroPublicBaseUrl?: string;
|
|
91
|
+
metroProxyBaseUrl?: string;
|
|
92
|
+
metroBearerToken?: string;
|
|
93
|
+
metroPreparePort?: number;
|
|
94
|
+
metroListenHost?: string;
|
|
95
|
+
metroStatusHost?: string;
|
|
96
|
+
metroStartupTimeoutMs?: number;
|
|
97
|
+
metroProbeTimeoutMs?: number;
|
|
98
|
+
metroRuntimeFile?: string;
|
|
99
|
+
metroNoReuseExisting?: boolean;
|
|
100
|
+
metroNoInstallDeps?: boolean;
|
|
101
|
+
};
|
|
102
|
+
type RemoteConnectionProfileFields = {
|
|
103
|
+
stateDir?: string;
|
|
104
|
+
daemonBaseUrl?: string;
|
|
105
|
+
daemonAuthToken?: string;
|
|
106
|
+
daemonTransport?: DaemonTransportPreference;
|
|
107
|
+
daemonServerMode?: DaemonServerMode;
|
|
108
|
+
tenant?: string;
|
|
109
|
+
sessionIsolation?: SessionIsolationMode;
|
|
110
|
+
runId?: string;
|
|
111
|
+
leaseId?: string;
|
|
112
|
+
leaseBackend?: LeaseBackend;
|
|
113
|
+
leaseProvider?: string;
|
|
114
|
+
deviceKey?: string;
|
|
115
|
+
clientId?: string;
|
|
116
|
+
};
|
|
117
|
+
type CloudProviderProfileFields = {
|
|
118
|
+
providerApp?: string;
|
|
119
|
+
providerOsVersion?: string;
|
|
120
|
+
providerProject?: string;
|
|
121
|
+
providerBuild?: string;
|
|
122
|
+
providerSessionName?: string;
|
|
123
|
+
awsProjectArn?: string;
|
|
124
|
+
awsDeviceArn?: string;
|
|
125
|
+
awsAppArn?: string;
|
|
126
|
+
awsRegion?: string;
|
|
127
|
+
awsInteractionMode?: 'INTERACTIVE' | 'NO_VIDEO' | 'VIDEO_ONLY';
|
|
128
|
+
};
|
|
129
|
+
type RemoteConfigProfile = RemoteConfigMetroOptions & CloudProviderProfileFields & RemoteConnectionProfileFields & {
|
|
130
|
+
platform?: PlatformSelector;
|
|
131
|
+
target?: DeviceTarget;
|
|
132
|
+
device?: string;
|
|
133
|
+
udid?: string;
|
|
134
|
+
serial?: string;
|
|
135
|
+
iosSimulatorDeviceSet?: string;
|
|
136
|
+
androidDeviceAllowlist?: string;
|
|
137
|
+
session?: string;
|
|
138
|
+
};
|
|
139
|
+
//#endregion
|
|
140
|
+
export { PrepareMetroRuntimeResult as a, MetroBridgeScope as c, MetroPrepareKind as i, RemoteConfigProfile as n, ReloadMetroResult as o, RemoteConnectionProfileFields as r, MetroBridgeDescriptor as s, CloudProviderProfileFields as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{l as e}from"./sdk-contracts.js";import{E as t}from"./sdk-android-adb.js";const n=[{key:`stateDir`,type:`string`,path:!0},{key:`daemonBaseUrl`,type:`string`},{key:`daemonAuthToken`,type:`string`},{key:`daemonTransport`,type:`enum`,enumValues:[`auto`,`socket`,`http`]},{key:`daemonServerMode`,type:`enum`,enumValues:[`socket`,`http`,`dual`]},{key:`tenant`,type:`string`},{key:`sessionIsolation`,type:`enum`,enumValues:[`none`,`tenant`]},{key:`runId`,type:`string`},{key:`leaseId`,type:`string`},{key:`leaseBackend`,type:`enum`,enumValues:[`ios-simulator`,`ios-instance`,`android-instance`]},{key:`platform`,type:`enum`,enumValues:e},{key:`target`,type:`enum`,enumValues:[`mobile`,`tv`,`desktop`]},{key:`device`,type:`string`},{key:`udid`,type:`string`},{key:`serial`,type:`string`},{key:`iosSimulatorDeviceSet`,type:`string`,path:!0,env:!1},{key:`androidDeviceAllowlist`,type:`string`},{key:`session`,type:`string`},{key:`providerApp`,type:`string`},{key:`providerOsVersion`,type:`string`},{key:`providerProject`,type:`string`},{key:`providerBuild`,type:`string`},{key:`providerSessionName`,type:`string`},{key:`awsProjectArn`,type:`string`},{key:`awsDeviceArn`,type:`string`},{key:`awsAppArn`,type:`string`},{key:`awsRegion`,type:`string`},{key:`awsInteractionMode`,type:`enum`,enumValues:[`INTERACTIVE`,`NO_VIDEO`,`VIDEO_ONLY`]},{key:`metroProjectRoot`,type:`string`,path:!0},{key:`metroKind`,type:`enum`,enumValues:[`auto`,`react-native`,`expo`]},{key:`metroPublicBaseUrl`,type:`string`},{key:`metroProxyBaseUrl`,type:`string`},{key:`metroBearerToken`,type:`string`},{key:`metroPreparePort`,type:`int`,min:1,max:65535},{key:`metroListenHost`,type:`string`},{key:`metroStatusHost`,type:`string`},{key:`metroStartupTimeoutMs`,type:`int`,min:1},{key:`metroProbeTimeoutMs`,type:`int`,min:1},{key:`metroRuntimeFile`,type:`string`,path:!0},{key:`metroNoReuseExisting`,type:`boolean`},{key:`metroNoInstallDeps`,type:`boolean`}],r=[{key:`leaseProvider`,type:`string`,env:!1},{key:`deviceKey`,type:`string`,env:!1},{key:`clientId`,type:`string`,env:!1}],i=[...n,...r],a=new Map(i.map(e=>[e.key,e]));function o(e){return a.get(e)}function s(e){return o(e)?.env===!1?[]:[t(e)]}export{o as i,i as n,s as r,n as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{O as e}from"./sdk-contracts.js";import{v as t,y as n}from"./sdk-batch.js";function r(e){let t=new Map;for(let[n,r]of e.entries())t.set(r.index,n);let n=[],r=[];for(let[i,a]of e.entries()){let e=Math.max(0,a.depth??0);for(;r.length>0&&e<=r[r.length-1].depth;)r.pop();let o=i,s=typeof a.parentIndex==`number`?t.get(a.parentIndex):void 0,c=typeof s==`number`&&s<o?s:r[r.length-1]?.index;n.push({...a,index:o,depth:e,parentIndex:c}),r.push({depth:e,index:o})}return n}function i(e){return new Map(e.map(e=>[e.index,e]))}function a(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||``}function o(e){let t=e.trim().toLowerCase();return t?/^(vertical|horizontal)\s+scroll\s+bar(?:,?\s*\d+\s+pages?)?$/.test(t):!1}function s(e,t){if(!(e?.trim().toLowerCase()??``).includes(`vertical scroll bar`))return null;let n=c(t);return n===null?null:n<=1?{above:!1,below:!0}:n>=99?{above:!0,below:!1}:{above:!0,below:!0}}function c(e){if(!e)return null;let t=/^(\d{1,3})%$/.exec(e.trim());if(!t)return null;let n=Number(t[1]);return Number.isFinite(n)?Math.max(0,Math.min(100,n)):null}function l(e){let t=p(e.label),n=p(e.value),r=p(e.identifier),i=g(r)?r:``;return h(e.type??``)?n||t||i:t||n||i}function u(e,t){if(t===`text-view`||t===`text-field`||t===`search`)return!0;let n=m(e.type??``),r=`${e.role??``} ${e.subrole??``}`.toLowerCase();return n.includes(`textview`)||n.includes(`textarea`)||n.includes(`textfield`)||n.includes(`securetextfield`)||n.includes(`searchfield`)||n.includes(`edittext`)||r.includes(`text area`)||r.includes(`text field`)}function d(e){let t=e.replace(/\s+/g,` `).trim();return t.length<=48?t:`${t.slice(0,45)}...`}function f(e,t){let n=l(e),r=u(e,t);return{text:n,isLargeSurface:r,shouldSummarize:r&&ee(n)}}function ee(e){return e?e.length>80||/[\r\n]/.test(e):!1}function p(e){return typeof e==`string`?e.trim():``}function m(e){let t=e.trim().replace(/XCUIElementType/gi,``).replace(/^AX/,``).toLowerCase(),n=Math.max(t.lastIndexOf(`.`),t.lastIndexOf(`/`));return n!==-1&&(t=t.slice(n+1)),t}function h(e){let t=m(e);return t.includes(`textfield`)||t.includes(`securetextfield`)||t.includes(`searchfield`)||t.includes(`edittext`)||t.includes(`textview`)||t.includes(`textarea`)}function g(e){return e?!/^[\w.]+:id\/[\w.-]+$/i.test(e)&&!/^_?NS:\d+$/i.test(e):!1}function _(t,n){let r=e(n),i=t.filter(e=>v(e.rect)),a=i.filter(e=>{let t=(e.type??``).toLowerCase();return t.includes(`application`)||t.includes(`window`)});return b(a.map(e=>e.rect).filter(e=>y(e,r.x,r.y)))||b(a.map(e=>e.rect))||b(i.map(e=>e.rect).filter(e=>y(e,r.x,r.y)))||null}function te(e,t){return x(e.x,e.x+e.width,t.x,t.x+t.width)&&x(e.y,e.y+e.height,t.y,t.y+t.height)}function v(e){return e?Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.width)&&Number.isFinite(e.height):!1}function y(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function b(e){let t=null,n=-1;for(let r of e){let e=r.width*r.height;e>n&&(t=r,n=e)}return t}function x(e,t,n,r){return Math.max(e,n)<=Math.min(t,r)}function S(e){let t=`${e??``}`.toLowerCase();return t.includes(`scroll`)||t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)||t.includes(`collectionview`)||t===`table`}function C(e){return S(e.type)?!0:`${e.role??``} ${e.subrole??``}`.toLowerCase().includes(`scroll`)}function w(e){if(e.length===0)return{nodes:e,hiddenCount:0,summaryLines:[]};let{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:i}=E(e),a=n.size===0?e:e.filter(e=>n.has(e.index));return{nodes:a.map(e=>oe(e,i.directionsByContainer)),hiddenCount:n.size===0?0:e.length-a.length,summaryLines:se(r.filter(e=>!i.coveredNodeIndexes.has(e.index)&&le(e)),e,t)}}function T(e){if(e.length===0)return new Map;let{hintedContainers:t}=E(e);return ae(t.directionsByContainer)}function E(e){let t=i(e),n=new Set,r=[];for(let i of e){if(D(i,e,t)){A(i,n,t);continue}r.push(i)}return{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:ie(e,r,n,t)}}function D(e,t,n=i(t)){if(!e.rect)return!0;let r=O(e,t,n);return r?te(e.rect,r):!0}function ne(e,t,n=i(t)){if(!e.rect)return!0;if(!D(e,t,n))return!1;let r=_(t,e.rect);return re(e.rect,r)}function re(e,t){return!t||t.width<=0||t.height<=0?!0:y(t,e.x+e.width/2,e.y+e.height/2)}function O(e,t,n=i(t)){return P(e,n)||_(t,e.rect??{x:0,y:0,width:0,height:0})}function ie(e,t,n,r){let i=new Map,a=new Map,o=new Set;for(let e of t){if(!e.rect)continue;let t=j(e,n,r);if(!t?.rect)continue;let s=k(e.rect,t.rect);if(!s)continue;let c=i.get(t.index)??new Set;c.add(s),i.set(t.index,c);let l=a.get(t.index)??new Set;l.add(s),a.set(t.index,l),o.add(e.index)}return M(e,n,r,i,a),{directionsByContainer:i,coveredNodeIndexes:o}}function ae(e){let t=new Map;for(let[n,r]of e){let e={};r.has(`above`)&&(e.hiddenContentAbove=!0),r.has(`below`)&&(e.hiddenContentBelow=!0),(e.hiddenContentAbove||e.hiddenContentBelow)&&t.set(n,e)}return t}function oe(e,t){let n=t.get(e.index);if(!n||n.size===0)return e;let r=e.hiddenContentAbove===!0||n.has(`above`)?!0:void 0,i=e.hiddenContentBelow===!0||n.has(`below`)?!0:void 0;return{...e,hiddenContentAbove:r,hiddenContentBelow:i}}function se(e,t,n){let r=new Map;for(let i of e){let e=ce(i,t,n);if(!e)continue;let a=r.get(e)??[];a.push(i),r.set(e,a)}return[`above`,`below`].flatMap(e=>{let t=r.get(e);if(!t||t.length===0)return[];let n=ue(t).slice(0,3).map(e=>`"${e}"`),i=t.length===1?`interactive item`:`interactive items`,a=n.length>0?`: ${n.join(`, `)}`:``;return[`[off-screen ${e}] ${t.length} ${i}${a}`]})}function ce(e,t,n){if(!e.rect)return null;let r=O(e,t,n);return r?k(e.rect,r):null}function k(e,t){return e.y+e.height<=t.y?`above`:e.y>=t.y+t.height?`below`:null}function le(e){if(e.hittable===!0)return!0;let t=(e.type??``).toLowerCase();return t.includes(`button`)||t.includes(`link`)||t.includes(`textfield`)||t.includes(`edittext`)||t.includes(`searchfield`)||t.includes(`checkbox`)||t.includes(`radio`)||t.includes(`switch`)||t.includes(`menuitem`)||!!a(e)}function ue(e){let t=new Set,n=[];for(let r of e){let e=a(r);!e||t.has(e)||(t.add(e),n.push(e))}return n}function A(e,t,n){let r=e,i=new Set;for(;r&&!i.has(r.index);)i.add(r.index),t.add(r.index),r=typeof r.parentIndex==`number`?n.get(r.parentIndex):void 0}function j(e,t,n){return F(e,n,e=>t.has(e.index))}function M(e,t,n,r,i){for(let a of e){let e=N(a);if(!e||e.size===0)continue;let o=j(a,t,n);if(!o)continue;let s=r.get(o.index)??new Set,c=i.get(o.index);for(let t of e)c&&c.size>0&&!c.has(t)||s.add(t);r.set(o.index,s)}}function N(e){let t=s(e.label,e.value);if(!t)return null;let n=new Set;return t.above&&n.add(`above`),t.below&&n.add(`below`),n.size>0?n:null}function P(e,t){return F(e,t,e=>!!e.rect)?.rect??null}function F(e,t,n){let r=typeof e.parentIndex==`number`?t.get(e.parentIndex):void 0,i=new Set;for(;r&&!i.has(r.index);){if(i.add(r.index),n(r)&&C(r))return r;r=typeof r.parentIndex==`number`?t.get(r.parentIndex):void 0}return null}function I(e,t){let n=t.toLowerCase();return e.find(e=>{let t=(e.label??``).toLowerCase(),r=(e.value??``).toLowerCase(),i=(e.identifier??``).toLowerCase();return t.includes(n)||r.includes(n)||i.includes(n)})??null}function L(e,t){let n=[e.label,e.value,e.identifier].map(e=>typeof e==`string`?e.trim():``).find(e=>e&&e.length>0);return n&&R(n)?n:z(e,t)??(n&&R(n)?n:void 0)}function R(e){let t=e.trim();return!(!t||/^(true|false)$/i.test(t)||/^\d+$/.test(t))}function z(e,t){if(!e.rect)return;let n=e.rect.y+e.rect.height/2,r=null;for(let e of t){if(!e.rect)continue;let t=[e.label,e.value,e.identifier].map(e=>typeof e==`string`?e.trim():``).find(e=>e&&e.length>0);if(!t||!R(t))continue;let i=e.rect.y+e.rect.height/2,a=Math.abs(i-n);(!r||a<r.distance)&&(r={label:t,distance:a})}return r?.label}function B(e){let t=[],n=[];for(let r of e){let e=r.depth??0;for(;t.length>0&&e<=t[t.length-1];)t.pop();let i=m(r.type??``),a=[r.label,r.value,r.identifier].map(e=>typeof e==`string`?e.trim():``).find(e=>e&&e.length>0),o=a?R(a):!1;if((i===`group`||i===`ioscontentgroup`)&&!o){t.push(e);continue}let s=Math.max(0,e-t.length);n.push({...r,depth:s})}return n}function V(e,t){let n=m(e);return n?t===`android`?n.includes(`edittext`)||n.includes(`autocompletetextview`):n.includes(`textfield`)||n.includes(`securetextfield`)||n.includes(`searchfield`)||n.includes(`textview`)||n.includes(`textarea`)||n===`search`:!0}function H(e,t){return t.hittable?t:G(e,t,e=>e.hittable===!0)}function U(e){return new Map(e.map(e=>[e.index,e]))}function W(e,t,n,r){let i=t,a=new Set;for(;typeof i.parentIndex==`number`&&!a.has(i.index);){if(a.add(i.index),i=n.get(i.parentIndex)??e[i.parentIndex],!i)return null;let t=r(i);if(t!==null)return t}return null}function de(e,t,n,r){return!!W(e,t,r,e=>e===n||e.index===n.index?e:null)}function G(e,t,n){return W(e,t,U(e),e=>n(e)?e:null)}function K(e){return[e.label,e.value,e.identifier].map(e=>typeof e==`string`?e.trim():``).filter(e=>e.length>0)[0]??``}function fe(e){return l(e)}function q(e){return e.hittable===!0?!0:e.rect?e.rect.width>0&&e.rect.height>0:!1}function J(e,t){return V(e.type??``,t)&&e.enabled!==!1}function Y(e){return[`visible`,`hidden`,`exists`,`editable`,`selected`,`text`].includes(e)}const pe=`is requires predicate: visible|hidden|exists|editable|selected|text`,me=`Use "is <predicate> <selector>" or "is <selector> <predicate>". visible|hidden|editable|selected double as selector keys: a bare predicate token after the selector is read as the predicate, so write key=true (e.g. visible=true) inside the selector to use it as a filter instead.`;function X(e){if(Y((e[0]??``).toLowerCase()))return e;for(let t=1;t<e.length;t+=1){let r=(e[t]??``).toLowerCase();if(Y(r)&&n(e.slice(0,t).join(` `)))return[r,...e.slice(0,t),...e.slice(t+1)]}return e}function he(e){let{predicate:t,node:n,nodes:r,expectedText:i,platform:a}=e,o=K(n),s=J(n,a),c=n.selected===!0,l=t===`text`?q(n):Z(n,r,a),u=!1;switch(t){case`visible`:u=l;break;case`hidden`:u=!l;break;case`editable`:u=s;break;case`selected`:u=c;break;case`text`:u=o===(i??``);break}let d=t===`text`?`expected="${i??``}" actual="${o}"`:`actual=${JSON.stringify({visible:l,editable:s,selected:c})}`;return{pass:u,actualText:o,details:d}}function Z(e,t,n){if(n===`android`&&e.visibleToUser===!1)return!1;if($(e.rect))return Q(e,t);if(e.rect)return!1;if(n!==`android`&&e.hittable===!0)return!0;let r=ge(e,t,n);return r?$(r.rect)?Q(r,t):n!==`android`&&r.hittable===!0:!1}function Q(e,t){return D(e,t)}function ge(e,t,n){return W(t,e,U(t),e=>_e(e,n)?e:null)}function _e(e,t){if(t===`android`&&e.visibleToUser===!1)return!1;let n=m(e.type??``);return n.includes(`application`)||n.includes(`window`)||n.includes(`scrollview`)||n.includes(`tableview`)||n.includes(`collectionview`)||n===`table`||n===`list`||n===`listview`?!1:t===`android`?e.hittable===!0&&$(e.rect):e.hittable===!0||$(e.rect)}function $(e){return!!(e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.width)&&Number.isFinite(e.height)&&e.width>0&&e.height>0)}function ve(e){let n=X(e),r=n[0]??``;return{predicate:r,split:t(n.slice(1),{preferTrailingValue:r===`text`})}}export{d as A,r as B,ne as C,y as D,S as E,p as F,s as I,o as L,l as M,m as N,b as O,h as P,i as R,D as S,C as T,V as _,Y as a,w as b,q as c,K as d,G as f,de as g,W as h,he as i,f as j,_ as k,U as l,I as m,pe as n,X as o,H as p,me as r,J as s,ve as t,fe as u,B as v,O as w,T as x,L as y,a as z};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{snapshotPresentationOptionsFromFlags as e,isMacOs as t,isApplePlatform as r,publicPlatformString as n,isIosFamily as s,buildSnapshotPresentationKey as o}from"./6849.js";import{setSessionSnapshot as i,createDaemonRuntimeSessionStore as a,context_contextFromFlags as l,captureSnapshot as c,dispatchCommand as u,requireCommandSupported as d,stopIosRunnerSession as f,errorResponse as p,resolveRunnerAppBundleId as m,getActiveAndroidSnapshotFreshness as g,noActiveSessionError as h,resolveTargetDevice as y,runAppleRunnerCommand as w}from"./9722.js";import{closeIosApp as S}from"./apps.js";import{emitDiagnostic as _}from"./8875.js";import{ensureDeviceReady as v,buildAppleRunnerRequestOptions as x}from"./8414.js";import{asAppError as k,normalizeError as I,AppError as A}from"./485.js";import{evaluateIsPredicate as P,isSupportedPredicate as N,localCommandPolicy as R,createAgentDevice as b}from"./7871.js";import{getAndroidAppState as q}from"./3340.js";import{splitIsSelectorArgs as C,normalizeType as M,prefersValueForReadableText as E,findNodeByLabel as D,extractNodeReadText as $}from"./893.js";import{resolveRectCenter as L,isSparseSnapshotQualityVerdict as O,parseWaitPositionals as K}from"./2948.js";import{parseFindArgs as F,tryParseSelectorChain as G}from"./587.js";async function V(e,t,r){let n=e.get(t),s=n?.device??await y(r??{});return n||await v(s),{session:n,device:s}}async function U(e,t,r){let n=!e&&s(t);try{return await r()}finally{n&&(await f(t.id),await T(t))}}async function T(e){let t=m();await S(e,t).catch(r=>{_({level:"debug",phase:"ios_sessionless_runner_host_close_failed",data:{deviceId:e.id,bundleId:t,error:r instanceof Error?r.message:String(r)}})})}function B(e,t,r,n){t&&e.recordAction(t,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:n})}function H(e){let{session:t,sessionName:r,device:n,snapshot:s,appBundleId:o}=e;return t?{...t,snapshot:s,lastComparisonSafeSnapshot:s?.comparisonSafe===!0?s:t.lastComparisonSafeSnapshot}:{name:r,device:n,createdAt:Date.now(),appBundleId:o,snapshot:s,...s?.comparisonSafe===!0?{lastComparisonSafeSnapshot:s}:{},actions:[]}}function j(e,t={}){return{artifacts:function(e,t={}){let r=!0===t.plural?"do":"does";return{resolveInput:async()=>{throw new A("UNSUPPORTED_OPERATION",`${e} ${r} not resolve input artifacts`)},reserveOutput:async()=>{throw new A("UNSUPPORTED_OPERATION",`${e} ${r} not reserve output artifacts`)},createTempFile:async()=>{throw new A("UNSUPPORTED_OPERATION",`${e} ${r} not create temporary files`)}}}(e,t),policy:R()}}let z=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function Q(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,n]of z)void 0!==e[r]&&t.push(n);return t}(t);return 0===r.length?null:p("INVALID_ARGS",`${e} @ref does not support ${r.join(", ")}.`)}async function W(e,t){let r=await J(e);if(r)throw new A("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}async function J(e){var t;if("android"!==e.device.platform||!e.appBundleId)return null;let r=await q(e.device),n=r.package?.trim();return n&&n!==e.appBundleId&&("com.android.settings"===(t=n)||"com.android.systemui"===t||"com.google.android.permissioncontroller"===t||t.includes("launcher"))?{expectedPackage:e.appBundleId,foregroundPackage:n,activity:r.activity,hint:"com.google.android.permissioncontroller"===n?"Dismiss or allow the permission prompt, then retry the smoke assertion.":"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."}:null}function X(e){return"COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage}function Y(e,t){let r=Array.isArray(e.selectorChain)?e.selectorChain:void 0,n=er(e),s=n?.kind==="ref"?en(n.ref):void 0,o=n?.kind==="selector"?n.selector:void 0,i={...s?{ref:s}:{},...o?{selector:o}:{},...r?{selectorChain:r}:{}};if("attrs"===t)return i;let a="string"==typeof e.text?e.text:"";return{...i,text:a,refLabel:function(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}(a)}}function Z(e){let t=er(e);return{...t?.kind==="ref"?{ref:en(t.ref)}:{},...t?.kind==="selector"?{selector:t.selector}:{},..."string"==typeof e.text?{text:e.text}:{},...e.node&&"object"==typeof e.node?{node:e.node}:{}}}function ee(e){let{selectorChain:t,...r}=e;return r}function et(e,t,r,n){let s=e.get(t);s&&e.recordAction(s,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:n})}function er(e){let t=e.target;return t&&"object"==typeof t?"ref"===t.kind&&"string"==typeof t.ref?{kind:"ref",ref:t.ref}:"selector"===t.kind&&"string"==typeof t.selector?{kind:"selector",selector:t.selector}:void 0:void 0}function en(e){return e.startsWith("@")?e.slice(1):e}let es=["application","window","tabbar","scrollbar","image"],eo=new Set(["tab bar"]);async function ei(e,t){var r;if(t.ok||(r=t.error.message,!/^wait timed out for (?:selector|text): /i.test(r)))return t;let n=await ea(e).catch(()=>null);return n?p(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}async function ea(e){let t=[...(await c({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0},logPath:e.logPath??""})).snapshot.nodes].sort(ec),r=el(t,6,{includeIdentifiers:!0});if(0===r.length)return null;let n=el(t.filter(e=>!ef(e)),4,{includeIdentifiers:!1}),s=el(t.filter(ep),4,{includeIdentifiers:!0});return{summary:(n.length>0?n:r.slice(0,4)).join(", "),details:{labels:r,...s.length>0?{buttons:s}:{}}}}function el(e,t,r){let n=new Set,s=[];for(let o of e){let e=ed(o,r);if(!(!e||n.has(e))&&(n.add(e),s.push(e),s.length>=t))break}return s}function ec(e,t){var r,n;return eu(e)-eu(t)||(r=e,n=t,r.rect&&n.rect?r.rect.y-n.rect.y||r.rect.x-n.rect.x:r.rect?-1:n.rect?1:(r.depth??0)-(n.depth??0)||r.index-n.index)}function eu(e){let t=!!ed(e,{includeIdentifiers:!1});return 2*!!ef(e)+ +!t}function ed(e,t){let r=(t.includeIdentifiers?[e.label,e.value,e.identifier]:[e.label,e.value]).map(e=>"string"==typeof e?e.trim():"").find(e=>e.length>0);return r?r.replace(/\s+/g," ").slice(0,80):""}function ef(e){let t=M(`${e.type??""} ${e.role??""} ${e.subrole??""}`),r=`${e.label??""} ${e.value??""}`.trim().toLowerCase();return es.some(e=>t.includes(e))||eo.has(r)||r.endsWith(".fill")}function ep(e){return M(`${e.type??""} ${e.role??""} ${e.subrole??""}`).includes("button")}function em(e){var t;let{session:r,selectorExpression:n}=e;if(!r||!s(r.device)||r.postGestureStabilization)return null;let o=G(n);if(!o||1!==o.selectors.length)return null;let i=o.selectors[0];if(!i||1!==i.terms.length)return null;let a=i.terms[0];return a&&"string"==typeof a.value&&("id"===(t=a.key)||"label"===t||"text"===t||"value"===t)?{key:a.key,value:a.value,raw:i.raw}:null}function eg(e,t={}){let r=k(e);if("ELEMENT_NOT_FOUND"===r.code)return!0===t.allowElementNotFound;if("COMMAND_FAILED"!==r.code)return!1;let n=r.message.toLowerCase();return n.includes("fetch failed")||n.includes("timed out")||n.includes("timeout")||n.includes("runner did not accept connection")||n.includes("invalid runner response")}async function eh(e){let{device:t,node:r,flags:n,appBundleId:o,traceOutPath:i,surface:a,contextFromFlags:l}=e,c=$(r),d=L(r.rect);if(!d||s(t)&&c&&!E(r.type??""))return c;try{let e=await u(t,"read",[String(d.x),String(d.y)],void 0,{...l(n,o,i),surface:a}),s=e&&"object"==typeof e?e:void 0,f="string"==typeof s?.text?s.text:"";if(f.trim())return f;return _({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:r.ref,surface:a,platform:t.platform}}),c}catch(e){return _({level:"warn",phase:"interaction_read_fallback",data:{reason:"backend_read_failed",nodeRef:r.ref,surface:a,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),c}}function ey(t){let r,n,{session:s,sessionStore:a,sessionName:l}=t,c=0;return{capture:async u=>{var d,f;let p=Date.now(),m=(d=u,f=t.req.flags?.out,JSON.stringify({presentationKey:o(e(ek(d))),includeRects:!0===d.includeRects,outPath:d.outPath??f??null})),h=function(e){let{timestamp:t,lastSnapshotAt:r,lastSnapshotResult:n,lastSnapshotCacheKey:s,session:o,request:i,cacheKey:a}=e;if(!(i.cache?.forceFresh===!0||!n||s!==a||t-r>=750||g(o))&&!ex(o,i))return n}({timestamp:p,lastSnapshotAt:c,lastSnapshotResult:r,lastSnapshotCacheKey:n,session:s,request:u,cacheKey:m});if(h)return h;let y=function(t){var r,n;let{session:s,timestamp:i,request:a}=t,l=s?.snapshot;if(l&&(r=s,n=a,!(n.cache?.forceFresh===!0||n.cache?.useSessionSnapshot!==!0||g(r)||ex(r,n)))&&i-l.createdAt<750&&l.presentationKey===function(t){return o(e(ek(t)))}(a))return l}({session:s,timestamp:p,request:u});if(y)return c=y.createdAt,r={snapshot:y},n=m,r;let w=await ew({params:t,request:u}),S={snapshot:w};return function(e){let{session:t,sessionStore:r,sessionName:n,snapshot:s}=e;!t||O(s.snapshotQuality)||(i(t,s),r.set(n,t))}({session:s,sessionStore:a,sessionName:l,snapshot:w}),c=p,r=S,n=m,S}}}async function ew(e){var t;let{params:r,request:n}=e,s=await ev(r,n,n.snapshotScope);return n.recovery?.legacyIosSparse&&!(t=s).snapshotQuality&&"xctest"===t.backend&&1===t.nodes.length&&t.nodes[0]?.type==="Application"?await eS({runtimeParams:r,request:n,policy:n.recovery.legacyIosSparse}):n.recovery?.sparseVerdictQueryScope?.shouldScope&&O(s.snapshotQuality)?await e_({runtimeParams:r,request:n,policy:n.recovery.sparseVerdictQueryScope,snapshot:s}):s}async function eS(e){let{runtimeParams:t,request:r,policy:n}=e;try{return await ev(t,r,n.scope,!1)}catch(e){if(!n.shouldScope)throw e;return await ev(t,r,n.query,!1)}}async function e_(e){let{runtimeParams:t,request:r,policy:n,snapshot:s}=e;try{return await ev(t,r,n.query,!1)}catch{return s}}async function ev(e,t,r,n=t.flags?.snapshotInteractiveOnly){return(await c({device:e.device,session:e.session,flags:{...t.flags,snapshotInteractiveOnly:n},outPath:t.outPath??e.req.flags?.out,logPath:e.logPath??"",snapshotScope:r,includeRects:t.includeRects})).snapshot}function ex(e,t){return t.cache?.bypassForPostGestureStabilization===!0&&!!e?.postGestureStabilization}function ek(e){return void 0===e.snapshotScope?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function eI(e){return b({backend:function(e){let{req:t,session:r,device:s,logPath:o,sessionName:i,sessionStore:a}=e,c=ey({device:s,session:r,sessionStore:a,sessionName:i,req:t,logPath:o});return{platform:n(s),captureSnapshot:async(e,r)=>{var n;let o,i={...t.flags,...(n=r,o={},n?.interactiveOnly!==void 0&&(o.snapshotInteractiveOnly=n.interactiveOnly),n?.scope!==void 0&&(o.snapshotScope=n.scope),n?.depth!==void 0&&(o.snapshotDepth=n.depth),n?.raw!==void 0&&(o.snapshotRaw=n.raw),o)},a=r?.includeRects===!0,l=r?.scope??t.flags?.snapshotScope,u="wait"===t.command||"find"===t.command||a&&"web"===s.platform;return await c.capture({flags:i,snapshotScope:l,includeRects:a,cache:{forceFresh:u,useSessionSnapshot:!0,bypassForPostGestureStabilization:!0}})},readText:async(n,i)=>({text:await eh({device:s,node:i,flags:t.flags,appBundleId:r?.appBundleId,traceOutPath:r?.trace?.outPath,surface:r?.surface,contextFromFlags:e.contextFromFlags??((e,t,r)=>l(o??"",e,t,r))})}),findText:async(t,r)=>({found:await eP(e,r)})}}(e),...j("selector commands",{plural:!0}),sessions:a({sessionName:e.sessionName,getSession:()=>e.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{e.session&&t.snapshot&&(i(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}})})}async function eA(e,t){let r=e.sessionStore.get(e.sessionName);if(!r&&t.requireSession)return{ok:!1,response:h()};let n=r?.device??await y(e.req.flags??{});r||await v(n);let s=d(t.capability,n);return s?{ok:!1,response:s}:{ok:!0,runtime:eI({...e,session:r,device:n})}}async function eP(e,t){let r=await eN(e,t);if(null!==r)return r;let n=await eR(e,t);return null!==n?n:await eb(e,t)}async function eN(e,r){return t(e.device)&&e.session?.surface&&"app"!==e.session.surface?await eb(e,r):null}async function eR(e,t){var n,s,o;let i=r((n=e).device.platform)&&n.session?.appBundleId?{device:n.device,appBundleId:n.session.appBundleId,traceLogPath:n.session.trace?.outPath}:null;if(!i)return null;let a=await w(i.device,{command:"findText",text:t,appBundleId:i.appBundleId},(s=e,o=i,x({req:s.req,logPath:s.logPath,traceLogPath:o.traceLogPath})));return a?.found===!0}async function eb(e,t){return!!D((await eq(e)).nodes,t)}async function eq(e){let t=ey({device:e.device,session:e.session,sessionStore:e.sessionStore,sessionName:e.sessionName,req:e.req,logPath:e.logPath}),{snapshot:r}=await t.capture({flags:{...e.req.flags,snapshotInteractiveOnly:!1},cache:{forceFresh:!0,bypassForPostGestureStabilization:!0}});return r}async function eC(e){var t;let{req:r}=e;if("find"!==r.command)return null;let n=r.positionals??[];if(0===n.length)return p("INVALID_ARGS","find requires a locator or text");let s=F(n);if(!s.query)return p("INVALID_ARGS","find requires a value");if(r.flags?.findFirst&&r.flags?.findLast)return p("INVALID_ARGS","find accepts only one of --first or --last");let o=s.action;if("exists"!==(t=o)&&"wait"!==t&&"get_text"!==t&&"get_attrs"!==t)return null;let i=await eA(e,{requireSession:!1,capability:"find"});return i.ok?await eU(async()=>{let t=await i.runtime.selectors.find({session:e.sessionName,requestId:r.meta?.requestId,locator:s.locator,query:s.query,action:o,timeoutMs:s.timeoutMs});return et(e.sessionStore,e.sessionName,r,function(e,t){if("exists"===t)return{found:!0};if("wait"===t)return{found:!0,waitedMs:e.waitedMs};let r="string"==typeof e.ref?e.ref:void 0;return"get_attrs"===t?{ref:r,action:"get attrs"}:{ref:r,action:"get text",text:"string"==typeof e.text?e.text:""}}(t,o)),"found"===t.kind?{found:!0,..."number"==typeof t.waitedMs?{waitedMs:t.waitedMs}:{}}:{..."string"==typeof t.ref?{ref:t.ref}:{},..."string"==typeof t.text?{text:t.text}:{},...t.node&&"object"==typeof t.node?{node:t.node}:{}}}):i.response}async function eM(e){let{req:t}=e;if("get"!==t.command)return null;let r=t.positionals?.[0];if("text"!==r&&"attrs"!==r)return p("INVALID_ARGS","get only supports text or attrs");let n=function(e){let t=e.positionals?.[1]??"";if(t.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(" ").trim():""}};let r=e.positionals?.slice(1).join(" ").trim()??"";return r?{ok:!0,target:{kind:"selector",selector:r}}:{ok:!1,response:p("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!n.ok)return n.response;if("ref"===n.target.kind){let e=Q("get",t.flags);if(e)return e}if("selector"===n.target.kind){let t=await e$(e,r,n.target.selector);if(t)return t}let s=await eA(e,{requireSession:!0,capability:"get"});return s.ok?await eU(async()=>{let o=await s.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:r,target:n.target});return et(e.sessionStore,e.sessionName,t,Y(o,r)),Z(o)}):s.response}async function eE(e){let{req:t}=e;if("is"!==t.command)return null;let r=(t.positionals?.[0]??"").toLowerCase();if(!N(r))return p("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:n}=C(t.positionals??[]);if(!n)return p("INVALID_ARGS","is requires a selector expression");let s=n.rest.join(" ").trim();if("text"===r&&!s)return p("INVALID_ARGS","is text requires expected text value");if("text"!==r&&n.rest.length>0)return p("INVALID_ARGS",`is ${r} does not accept trailing values`);let o=await eL(e,r,n.selectorExpression,s);if(o)return o;let i=await eA(e,{requireSession:!0,capability:"is"});if(!i.ok)return i.response;let a=await eU(async()=>{let o=await i.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:r,selector:n.selectorExpression,expectedText:s});return et(e.sessionStore,e.sessionName,t,o),ee(o)});return await eT(e,a,`is ${r}`)}async function eD(e){let{req:t,sessionName:r,sessionStore:n}=e,s=K(t.positionals??[]);if(!s)return p("INVALID_ARGS","wait requires a duration or text");let{session:o,device:i}=await V(n,r,t.flags);if("sleep"!==s.kind){let e=d("wait",i);if(e)return e}if("selector"===s.kind){let t=await eO({...e,session:o,device:i,selectorExpression:s.selectorExpression,timeoutMs:s.timeoutMs});if(t)return t}let a=async()=>{let a=eI({...e,session:o,device:i}),l=await eU(async()=>{let e=await a.selectors.wait({session:r,requestId:t.meta?.requestId,target:function(e,t){if("sleep"===e.kind)return{kind:"sleep",durationMs:e.durationMs};if("selector"===e.kind)return{kind:"selector",selector:e.selectorExpression,timeoutMs:e.timeoutMs};if("ref"===e.kind){if(!t?.snapshot)throw new A("INVALID_ARGS","Ref wait requires an existing snapshot in session.");return{kind:"ref",ref:e.rawRef,timeoutMs:e.timeoutMs}}if(!e.text)throw new A("INVALID_ARGS","wait requires text");return{kind:"text",text:e.text,timeoutMs:e.timeoutMs}}(s,o)});return et(n,r,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}}),c=await ei({req:t,logPath:e.logPath,session:o,device:i},l);return await eT(e,c,"wait")};return"sleep"===s.kind?await a():await U(o,i,a)}async function e$(e,t,r){let n=e.sessionStore.get(e.sessionName),s=em({session:n,selectorExpression:r});if(!n||!s||"text"===t&&"id"!==s.key)return null;let o=await eG(e,n,s);if(eV(o))return o.response;if(!o)return null;let i=function(e,t,r){if(!r.found||!r.node)return null;let n={target:{kind:"selector",selector:t},node:r.node,selectorChain:[t]};return"attrs"===e?{kind:"attrs",...n}:"string"!=typeof r.text?null:{kind:"text",...n,text:r.text}}(t,s.raw,o);return i?(et(e.sessionStore,e.sessionName,e.req,Y(i,t)),{ok:!0,data:Z(i)}):null}async function eL(e,t,r,n){var s,o,i,a,l;let c;if("hidden"===t)return null;let u=await eK(e,r);if(eV(u))return u.response;if(!u?.result.found||!u.result.node)return null;let d="exists"===t?{predicate:t,pass:!0,selector:u.selector.raw,matches:1,selectorChain:[u.selector.raw]}:(s=t,o=n,i=u.selector.raw,a=u.session,c=P({predicate:s,node:l=u.result.node,nodes:[l],expectedText:o,platform:a.device.platform}),{predicate:s,pass:c.pass,selector:i,..."text"===s?{text:c.actualText}:{},selectorChain:[i]});return d?(et(e.sessionStore,e.sessionName,e.req,d),{ok:!0,data:ee(d)}):null}async function eO(e){let t=em({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let r=Date.now(),n=await eG(e,e.session,t);if(eV(n))return n.response;if(!n?.found)return null;let s={kind:"selector",selector:t.raw,waitedMs:Date.now()-r,selectorChain:[t.raw]};return et(e.sessionStore,e.sessionName,e.req,s),await ei({req:e.req,logPath:e.logPath,session:e.session,device:e.device},{ok:!0,data:s})}async function eK(e,t){let r=e.sessionStore.get(e.sessionName),n=em({session:r,selectorExpression:t});if(!r||!n)return null;let s=await eG(e,r,n);return eV(s)?s:s?{session:r,selector:n,result:s}:null}async function eF(e,t,r){let n=await w(t.device,{command:"querySelector",selectorKey:r.key,selectorValue:r.value,appBundleId:t.appBundleId},x({req:e.req,logPath:e.logPath,traceLogPath:t.trace?.outPath})),s=!0===n.found,o=function(e){let t=e.nodes;if(!Array.isArray(t))return;let r=t[0];if(r&&"object"==typeof r)return r}(n);return{found:s,..."string"==typeof n.text?{text:n.text}:{},...o?{node:o}:{}}}async function eG(e,t,r){try{return await eF(e,t,r)}catch(e){if(eg(e,{allowElementNotFound:!0}))return null;return{kind:"error",response:{ok:!1,error:I(e)}}}}function eV(e){return null!==e&&"kind"in e&&"error"===e.kind}async function eU(e){try{return{ok:!0,data:await e()}}catch(t){let e=k(t);return p(e.code,e.message,e.details)}}async function eT(e,t,r){var n;let s;if(t.ok)return t;let o=e.sessionStore.get(e.sessionName);if(!o)return t;try{s=await J(o)}catch{return t}return s?p(t.error.code,`${r} failed because ${"com.google.android.permissioncontroller"===(n=s).foregroundPackage?`Android permission dialog is blocking ${n.expectedPackage}`:`${n.foregroundPackage} is foreground instead of ${n.expectedPackage}`}.`,{...t.error.details??{},...s,blockedBy:"android_foreground_surface",originalMessage:t.error.message}):t}export{W as assertAndroidPressStayedInApp,H as buildSnapshotSession,j as createDaemonRuntimePolicy,ey as createSelectorCaptureRuntime,eC as dispatchFindReadOnlyViaRuntime,eM as dispatchGetViaRuntime,eE as dispatchIsViaRuntime,eD as dispatchWaitViaRuntime,X as isAndroidEscapeError,eg as isDirectIosSelectorFallbackError,em as readSimpleIosSelectorTarget,eh as readTextForNode,B as recordIfSession,Q as refSnapshotFlagGuardResponse,V as resolveSessionDevice,U as withSessionlessRunnerCleanup};
|
|
1
|
+
import{B as e,D as t,F as n,I as r,M as i,N as a,T as o,b as s,f as c,m as l,p as u}from"./sdk-contracts.js";import{j as d}from"./sdk-android-adb.js";import{h as f,y as p}from"./sdk-batch.js";import{H as ee,c as m}from"./device-rotation.js";import{N as h,P as te,a as ne,i as re,m as ie,n as ae,r as oe,t as se,u as ce}from"./sdk-selectors.js";import{t as le}from"./snapshot-quality.js";import{a as ue}from"./sdk-finders.js";import"./selectors2.js";import{n as de,t as fe}from"./runtime.js";import{r as pe}from"./app-lifecycle.js";import{c as me,f as he,i as g}from"./runner-client.js";import{Et as ge,Ht as _e,It as ve,Ot as _,Qt as v,Tt as ye,Xt as y,Zt as be,jt as b,kt as x,on as S,zt as C}from"./internal/daemon.js";import{a as w,t as T}from"./apple-runner-options.js";import{o as xe}from"./apps.js";function E(e){if(e.length<2)return null;let t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:{x:t,y:n}}async function D(e){let{device:t,node:n,flags:r,appBundleId:i,traceOutPath:a,surface:o,contextFromFlags:s}=e,c=ce(n),l=ee(n.rect);if(!l||u(t)&&c&&!te(n.type??``))return c;try{let e=await _e(t,`read`,[String(l.x),String(l.y)],void 0,{...s(r,i,a),surface:o}),u=e&&typeof e==`object`?e:void 0,f=typeof u?.text==`string`?u.text:``;return f.trim()?f:(d({level:`warn`,phase:`interaction_read_fallback`,data:{reason:`empty_backend_text`,nodeRef:n.ref,surface:o,platform:t.platform}}),c)}catch(e){return d({level:`warn`,phase:`interaction_read_fallback`,data:{reason:`backend_read_failed`,nodeRef:n.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),c}}async function O(e,t,n){let r=e.get(t),i=r?.device??await S(n??{});return r||await w(i),{session:r,device:i}}async function k(e,t,n){let r=!e&&u(t);try{return await n()}finally{r&&(await me(t.id),await Se(t))}}async function Se(e){let t=he();await xe(e,t).catch(n=>{d({level:`debug`,phase:`ios_sessionless_runner_host_close_failed`,data:{deviceId:e.id,bundleId:t,error:n instanceof Error?n.message:String(n)}})})}function Ce(e,t,n,r){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function we(e){let{session:t,sessionName:n,device:r,snapshot:i,appBundleId:a}=e;return t?{...t,snapshot:i,lastComparisonSafeSnapshot:i?.comparisonSafe===!0?i:t.lastComparisonSafeSnapshot}:{name:n,device:r,createdAt:Date.now(),appBundleId:a,snapshot:i,...i?.comparisonSafe===!0?{lastComparisonSafeSnapshot:i}:{},actions:[]}}const Te=[[`snapshotDepth`,`--depth`],[`snapshotScope`,`--scope`],[`snapshotRaw`,`--raw`]];function A(e,t){let n=Ee(t);return n.length===0?null:y(`INVALID_ARGS`,`${e} @ref does not support ${n.join(`, `)}.`)}function Ee(e){if(!e)return[];let t=[];for(let[n,r]of Te)e[n]!==void 0&&t.push(r);return t}function De(e,t){if(!t||t.settle===!0)return null;let n=[];return t.settleQuietMs!==void 0&&n.push(`--settle-quiet`),n.length===0?null:y(`INVALID_ARGS`,`${e}: ${n.join(`, `)} require${n.length===1?`s`:``} --settle.`)}function Oe(e){if(e?.settle===!0)return{...e.settleQuietMs===void 0?{}:{quietMs:e.settleQuietMs},...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}}}function j(e){let t=a(e);return t?{ok:!0,ref:t.base,generation:t.generation}:{ok:!1,response:y(`INVALID_ARGS`,`Invalid ref "${e}" — malformed generation suffix.`,{hint:o})}}function ke(e,t){let n=E(e);if(n)return{ok:!0,target:{kind:`point`,x:n.x,y:n.y}};let r=e[0]??``;if(r.startsWith(`@`)){let t=j(r);return t.ok?{ok:!0,target:{kind:`ref`,ref:t.ref,fallbackLabel:e.slice(1).join(` `).trim()},refGeneration:t.generation}:{ok:!1,response:t.response}}let i=e.join(` `).trim();return i?{ok:!0,target:{kind:`selector`,selector:i}}:{ok:!1,response:y(`INVALID_ARGS`,`${t} requires @ref, selector expression, or x y coordinates`)}}function Ae(e){let t=E(e);if(t)return{ok:!0,target:{kind:`point`,x:t.x,y:t.y},...Le(e[2])};let n=Ie(e),r=ke(n.targetPositionals,`longpress`);return r.ok?{ok:!0,target:r.target,refGeneration:r.refGeneration,...n.duration}:r}function je(e){let t=e[0]??``;if(t.startsWith(`@`)){let n=j(t);if(!n.ok)return{ok:!1,response:n.response};let r=m(e).text;return r?{ok:!0,target:{kind:`ref`,ref:n.ref,fallbackLabel:Fe(e)},refGeneration:n.generation,text:r}:{ok:!1,response:y(`INVALID_ARGS`,`fill requires text after ref`)}}let n=E(e);if(n){let t=e.slice(2).join(` `);return t?{ok:!0,target:{kind:`point`,x:n.x,y:n.y},text:t}:{ok:!1,response:y(`INVALID_ARGS`,`fill requires text after coordinates`)}}let r=Me(e);return!r||r.kind!==`selector`?{ok:!1,response:y(`INVALID_ARGS`,`fill requires x y text, @ref text, or selector text`)}:r.text.trim()?{ok:!0,target:{kind:`selector`,selector:r.target.selector},text:r.text}:{ok:!1,response:y(`INVALID_ARGS`,`fill requires text after selector`)}}function Me(e){try{return m(e)}catch{return null}}function Ne(e){let t=`evidence`in e?e.evidence:void 0,n=e.settle;return e.kind===`ref`?{ref:M(e.target?.kind===`ref`?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n}:e.kind===`selector`?{selector:e.target?.kind===`selector`?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n}:{evidence:t,settle:n}}function Pe(e,t){return e.kind===`point`?`coordinate tap`:t.kind===`ref`&&t.target?.kind===`ref`?t.target.ref:t.kind===`selector`&&t.target?.kind===`selector`?t.target.selector:`target`}function M(e){return e?.startsWith(`@`)?e.slice(1):e}function Fe(e){return e.length>=3&&e[1]?.trim()||``}function Ie(e){let t=e.at(-1);return e.length>1&&Re(t)?{targetPositionals:e.slice(0,-1),duration:{durationMs:Number(t)}}:{targetPositionals:e,duration:{}}}function Le(e){return e===void 0?{}:{durationMs:Number(e)}}function Re(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}async function ze(e,t){let r=await N(e);if(r)throw new n(`COMMAND_FAILED`,`press ${t} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}async function N(e){if(e.device.platform!==`android`||!e.appBundleId)return null;let t=await pe(e.device),n=t.package?.trim();return!n||n===e.appBundleId||!Ue(n)?null:{expectedPackage:e.appBundleId,foregroundPackage:n,activity:t.activity,hint:He(n)}}function Be(e){return e.foregroundPackage===`com.google.android.permissioncontroller`?`Android permission dialog is blocking ${e.expectedPackage}`:`${e.foregroundPackage} is foreground instead of ${e.expectedPackage}`}function Ve(e){return e.code===`COMMAND_FAILED`&&typeof e.details?.expectedPackage==`string`&&typeof e.details?.foregroundPackage==`string`}function He(e){return e===`com.google.android.permissioncontroller`?`Dismiss or allow the permission prompt, then retry the smoke assertion.`:`Use screenshot as visual truth, then take a fresh snapshot -i before retrying.`}function Ue(e){return e===`com.android.settings`||e===`com.android.systemui`||e===`com.google.android.permissioncontroller`||e.includes(`launcher`)}function We(e,t){if(t===`exists`)return{found:!0};if(t===`wait`)return{found:!0,waitedMs:e.waitedMs};let n=typeof e.ref==`string`?e.ref:void 0;return t===`get_attrs`?{ref:n,action:`get attrs`}:{ref:n,action:`get text`,text:typeof e.text==`string`?e.text:``}}function Ge(e){return e.kind===`found`?{found:!0,...typeof e.waitedMs==`number`?{waitedMs:e.waitedMs}:{}}:{...typeof e.ref==`string`?{ref:e.ref}:{},...typeof e.text==`string`?{text:e.text}:{},...e.node&&typeof e.node==`object`?{node:e.node}:{}}}function P(e,t){let n=Array.isArray(e.selectorChain)?e.selectorChain:void 0,r=R(e),i=r?.kind===`ref`?z(r.ref):void 0,a=r?.kind===`selector`?r.selector:void 0,o={...i?{ref:i}:{},...a?{selector:a}:{},...n?{selectorChain:n}:{}};if(t===`attrs`)return o;let s=typeof e.text==`string`?e.text:``;return{...o,text:s,refLabel:qe(s)}}function F(e){let t=R(e);return{...t?.kind===`ref`?{ref:z(t.ref)}:{},...t?.kind===`selector`?{selector:t.selector}:{},...typeof e.text==`string`?{text:e.text}:{},...e.node&&typeof e.node==`object`?{node:e.node}:{}}}function Ke(e){return{waitedMs:e.waitedMs,...typeof e.text==`string`?{text:e.text}:{},...typeof e.selector==`string`?{selector:e.selector}:{},...typeof e.captures==`number`?{captures:e.captures}:{},...typeof e.nodeCount==`number`?{nodeCount:e.nodeCount}:{},...typeof e.hint==`string`?{hint:e.hint}:{}}}function I(e){let{selectorChain:t,...n}=e;return n}function L(e,t,n,r){let i=e.get(t);i&&e.recordAction(i,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function qe(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}function R(e){let t=e.target;if(!t||typeof t!=`object`)return;let n=t;if(n.kind===`ref`&&typeof n.ref==`string`)return{kind:`ref`,ref:n.ref};if(n.kind===`selector`&&typeof n.selector==`string`)return{kind:`selector`,selector:n.selector}}function z(e){return e.startsWith(`@`)?e.slice(1):e}const Je=[`application`,`window`,`tabbar`,`scrollbar`,`image`],Ye=new Set([`tab bar`]);async function B(e,t){if(t.ok||!Xe(t.error.message)||t.error.details?.captureStalled===!0)return t;let n=await Ze(e).catch(()=>null);return n?y(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}function Xe(e){return/^wait timed out (?:for (?:selector|text): |waiting for a stable UI)/i.test(e)}async function Ze(e){let t=[...(await b({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0},logPath:e.logPath??``})).snapshot.nodes].sort(Qe),n=V(t,6,{includeIdentifiers:!0});if(n.length===0)return null;let r=V(t.filter(e=>!W(e)),4,{includeIdentifiers:!1}),i=V(t.filter(et),4,{includeIdentifiers:!0});return{summary:(r.length>0?r:n.slice(0,4)).join(`, `),details:{labels:n,...i.length>0?{buttons:i}:{}}}}function V(e,t,n){let r=new Set,i=[];for(let a of e){let e=U(a,n);if(!(!e||r.has(e))&&(r.add(e),i.push(e),i.length>=t))break}return i}function Qe(e,t){return H(e)-H(t)||$e(e,t)}function H(e){let t=!!U(e,{includeIdentifiers:!1});return(W(e)?2:0)+ +!t}function $e(e,t){return e.rect&&t.rect?e.rect.y-t.rect.y||e.rect.x-t.rect.x:e.rect?-1:t.rect?1:(e.depth??0)-(t.depth??0)||e.index-t.index}function U(e,t){let n=(t.includeIdentifiers?[e.label,e.value,e.identifier]:[e.label,e.value]).map(e=>typeof e==`string`?e.trim():``).find(e=>e.length>0);return n?n.replace(/\s+/g,` `).slice(0,80):``}function W(e){let t=h(`${e.type??``} ${e.role??``} ${e.subrole??``}`),n=`${e.label??``} ${e.value??``}`.trim().toLowerCase();return Je.some(e=>t.includes(e))||Ye.has(n)||n.endsWith(`.fill`)}function et(e){return h(`${e.type??``} ${e.role??``} ${e.subrole??``}`).includes(`button`)}function G(e){let{session:t,selectorExpression:n}=e;if(!t||!u(t.device)||t.postGestureStabilization)return null;let r=p(n);if(!r||r.selectors.length!==1)return null;let i=r.selectors[0];if(!i||i.terms.length!==1)return null;let a=i.terms[0];return!a||typeof a.value!=`string`||!tt(a.key)?null:{key:a.key,value:a.value,raw:i.raw}}function tt(e){return e===`id`||e===`label`||e===`text`||e===`value`}function K(e,t={}){let n=r(e);if(n.code===`ELEMENT_NOT_FOUND`)return t.delegateSemanticFailures===!0||t.allowElementNotFound===!0;if(n.code===`AMBIGUOUS_MATCH`)return t.delegateSemanticFailures===!0;if(n.code===`ELEMENT_OFFSCREEN`)return!0;if(n.code!==`COMMAND_FAILED`)return!1;let i=n.message.toLowerCase();return i.includes(`fetch failed`)||i.includes(`timed out`)||i.includes(`timeout`)||i.includes(`runner did not accept connection`)||i.includes(`invalid runner response`)}function nt(e,t={}){let r=t.plural===!0?`do`:`does`;return{resolveInput:async()=>{throw new n(`UNSUPPORTED_OPERATION`,`${e} ${r} not resolve input artifacts`)},reserveOutput:async()=>{throw new n(`UNSUPPORTED_OPERATION`,`${e} ${r} not reserve output artifacts`)},createTempFile:async()=>{throw new n(`UNSUPPORTED_OPERATION`,`${e} ${r} not create temporary files`)}}}function rt(e,t={}){return{artifacts:nt(e,t),policy:de()}}function q(e){let{session:t,sessionStore:n,sessionName:r}=e,i=0,a,o;return{capture:async s=>{let c=Date.now(),l=pt(s,e.req.flags?.out),u=st({timestamp:c,lastSnapshotAt:i,lastSnapshotResult:a,lastSnapshotCacheKey:o,session:t,request:s,cacheKey:l});if(u)return u;let d=ct({session:t,timestamp:c,request:s});if(d)return i=d.createdAt,a={snapshot:d},o=l,a;let f=await it({params:e,request:s}),p={snapshot:f};return ht({session:t,sessionStore:n,sessionName:r,snapshot:f}),i=c,a=p,o=l,p}}}async function it(e){let{params:t,request:n}=e,r=await J(t,n,n.snapshotScope);return n.recovery?.legacyIosSparse&>(r)?await at({runtimeParams:t,request:n,policy:n.recovery.legacyIosSparse}):n.recovery?.sparseVerdictQueryScope?.shouldScope&&le(r.snapshotQuality)?await ot({runtimeParams:t,request:n,policy:n.recovery.sparseVerdictQueryScope,snapshot:r}):r}async function at(e){let{runtimeParams:t,request:n,policy:r}=e;try{return await J(t,n,r.scope,!1)}catch(e){if(!r.shouldScope)throw e;return await J(t,n,r.query,!1)}}async function ot(e){let{runtimeParams:t,request:n,policy:r,snapshot:i}=e;try{return await J(t,n,r.query,!1)}catch{return i}}async function J(e,t,n,r=t.flags?.snapshotInteractiveOnly){return(await b({device:e.device,session:e.session,flags:{...t.flags,snapshotInteractiveOnly:r},outPath:t.outPath??e.req.flags?.out,logPath:e.logPath??``,snapshotScope:n,includeRects:t.includeRects})).snapshot}function st(e){let{timestamp:t,lastSnapshotAt:n,lastSnapshotResult:r,lastSnapshotCacheKey:i,session:a,request:o,cacheKey:s}=e;if(o.cache?.forceFresh!==!0&&r&&i===s&&!(t-n>=750)&&!C(a)&&!dt(a,o))return r}function ct(e){let{session:t,timestamp:n,request:r}=e,i=t?.snapshot;if(i&<(t,r)&&ut(i,n)&&i.presentationKey===ft(r))return i}function lt(e,t){return!(t.cache?.forceFresh===!0||t.cache?.useSessionSnapshot!==!0||C(e)||dt(e,t))}function ut(e,t){return t-e.createdAt<750}function dt(e,t){return t.cache?.bypassForPostGestureStabilization===!0&&!!e?.postGestureStabilization}function ft(e){return t(i(mt(e)))}function pt(e,t){return JSON.stringify({presentationKey:ft(e),includeRects:e.includeRects===!0,outPath:e.outPath??t??null})}function mt(e){return e.snapshotScope===void 0?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function ht(e){let{session:t,sessionStore:n,sessionName:r,snapshot:i}=e;!t||le(i.snapshotQuality)||(x(t,i),n.set(r,t))}function gt(e){return e.snapshotQuality||e.backend!==`xctest`||e.nodes.length!==1?!1:e.nodes[0]?.type===`Application`}function _t(e){return fe({backend:vt(e),...rt(`selector commands`,{plural:!0}),sessions:ye({sessionName:e.sessionName,getSession:()=>e.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{!e.session||!t.snapshot||(x(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}})})}async function Y(e,t){let n=e.sessionStore.get(e.sessionName);if(!n&&t.requireSession)return{ok:!1,response:be()};let r=n?.device??await S(e.req.flags??{});n||await w(r);let i=v(t.capability,r);return i?{ok:!1,response:i}:{ok:!0,runtime:_t({...e,session:n,device:r})}}function vt(e){let{req:t,session:n,device:r,logPath:i,sessionName:a,sessionStore:o}=e,c=q({device:r,session:n,sessionStore:o,sessionName:a,req:t,logPath:i});return{platform:s(r),captureSnapshot:async(e,n)=>{let i={...t.flags,...yt(n)},a=n?.includeRects===!0,o=n?.scope??t.flags?.snapshotScope,s=t.command===`wait`||t.command===`find`||a&&r.platform===`web`;return await c.capture({flags:i,snapshotScope:o,includeRects:a,cache:{forceFresh:s,useSessionSnapshot:!0,bypassForPostGestureStabilization:!0}})},readText:async(a,o)=>({text:await D({device:r,node:o,flags:t.flags,appBundleId:n?.appBundleId,traceOutPath:n?.trace?.outPath,surface:n?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>ve(i??``,e,t,n))})}),findText:async(t,n)=>({found:await bt(e,n)})}}function yt(e){let t={};return e?.interactiveOnly!==void 0&&(t.snapshotInteractiveOnly=e.interactiveOnly),e?.scope!==void 0&&(t.snapshotScope=e.scope),e?.depth!==void 0&&(t.snapshotDepth=e.depth),e?.raw!==void 0&&(t.snapshotRaw=e.raw),t}async function bt(e,t){let n=await xt(e,t);if(n!==null)return n;let r=await St(e,t);return r===null?await Tt(e,t):r}async function xt(e,t){return!l(e.device)||!e.session?.surface||e.session.surface===`app`?null:await Tt(e,t)}async function St(e,t){let n=Ct(e);return n?(await g(n.device,{command:`findText`,text:t,appBundleId:n.appBundleId},wt(e,n)))?.found===!0:null}function Ct(e){return!c(e.device.platform)||!e.session?.appBundleId?null:{device:e.device,appBundleId:e.session.appBundleId,traceLogPath:e.session.trace?.outPath}}function wt(e,t){return T({req:e.req,logPath:e.logPath,traceLogPath:t.traceLogPath})}async function Tt(e,t){return!!ie((await Et(e)).nodes,t)}async function Et(e){let{snapshot:t}=await q({device:e.device,session:e.session,sessionStore:e.sessionStore,sessionName:e.sessionName,req:e.req,logPath:e.logPath}).capture({flags:{...e.req.flags,snapshotInteractiveOnly:!1},cache:{forceFresh:!0,bypassForPostGestureStabilization:!0}});return t}async function Dt(e){let{req:t}=e;if(t.command!==`find`)return null;let n=t.positionals??[];if(n.length===0)return y(`INVALID_ARGS`,`find requires a locator or text`);let r=ue(n);if(!r.query)return y(`INVALID_ARGS`,`find requires a value`);if(t.flags?.findFirst&&t.flags?.findLast)return y(`INVALID_ARGS`,`find accepts only one of --first or --last`);let i=r.action;if(!Vt(i))return null;let a=await Y(e,{requireSession:!1,capability:`find`});return a.ok?await Q(async()=>{let n=await a.runtime.selectors.find({session:e.sessionName,requestId:t.meta?.requestId,locator:r.locator,query:r.query,action:i,timeoutMs:r.timeoutMs});L(e.sessionStore,e.sessionName,t,We(n,i));let o=Ge(n);if(typeof o.ref==`string`){let t=e.sessionStore.get(e.sessionName);if(t&&(ge(t),e.sessionStore.set(e.sessionName,t),t.snapshotGeneration!==void 0))return{...o,refsGeneration:t.snapshotGeneration}}return o}):a.response}async function Ot(e){let{req:t}=e;if(t.command!==`get`)return null;let n=t.positionals?.[0];if(n!==`text`&&n!==`attrs`)return y(`INVALID_ARGS`,`get only supports text or attrs`);let r=zt(t);if(!r.ok)return r.response;if(r.target.kind===`ref`){let e=A(`get`,t.flags);if(e)return e}if(r.target.kind===`selector`){let t=await jt(e,n,r.target.selector);if(t)return t}let i=await Y(e,{requireSession:!0,capability:`get`});if(!i.ok)return i.response;let a=r.target.kind===`ref`?_({session:e.sessionStore.get(e.sessionName),ref:r.target.ref,mintedGeneration:r.refGeneration}):void 0;return await Q(async()=>{let o=await i.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:n,target:r.target});L(e.sessionStore,e.sessionName,t,P(o,n));let s=F(o);return a?{...s,warning:a}:s})}async function kt(e){let{req:t}=e;if(t.command!==`is`)return null;let{predicate:n,split:r}=se(t.positionals??[]),i=n.toLowerCase();if(!ne(i))return y(`INVALID_ARGS`,ae,{hint:oe});if(!r)return y(`INVALID_ARGS`,`is requires a selector expression`);let a=r.rest.join(` `).trim();if(i===`text`&&!a)return y(`INVALID_ARGS`,`is text requires expected text value`);if(i!==`text`&&r.rest.length>0)return y(`INVALID_ARGS`,`is ${i} does not accept trailing values`);let o=await Mt(e,i,r.selectorExpression,a);if(o)return o;let s=await Y(e,{requireSession:!0,capability:`is`});return s.ok?await $(e,await Q(async()=>{let n=await s.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:i,selector:r.selectorExpression,expectedText:a});return L(e.sessionStore,e.sessionName,t,n),I(n)}),`is ${i}`):s.response}async function At(e){let{req:t,sessionName:n,sessionStore:r}=e,i=f(t.positionals??[]);if(!i)return y(`INVALID_ARGS`,`wait requires a duration or text`);let{session:a,device:o}=await O(r,n,t.flags);if(i.kind!==`sleep`){let e=v(`wait`,o);if(e)return e}if(i.kind===`selector`){let t=await Nt({...e,session:a,device:o,selectorExpression:i.selectorExpression,timeoutMs:i.timeoutMs});if(t)return t}let s=i,c;if(i.kind===`ref`){let e=j(i.rawRef);if(!e.ok)return e.response;s={...i,rawRef:e.ref},c=_({session:a,ref:e.ref,mintedGeneration:e.generation})}let l=async()=>{let i=_t({...e,session:a,device:o}),l=await Q(async()=>{let e=await i.selectors.wait({session:n,requestId:t.meta?.requestId,target:Bt(s,a)});L(r,n,t,e);let o=Ke(e);return c?{...o,warning:c}:o});return await $(e,await B({req:t,logPath:e.logPath,session:a,device:o},l),`wait`)};return i.kind===`sleep`?await l():await k(a,o,l)}async function jt(e,t,n){let r=e.sessionStore.get(e.sessionName),i=G({session:r,selectorExpression:n});if(!r||!i||t===`text`&&i.key!==`id`)return null;let a=await X(e,r,i);if(Z(a))return a.response;if(!a)return null;let o={session:r,selector:i,result:a},s=It(t,o.selector.raw,o.result);return s?(L(e.sessionStore,e.sessionName,e.req,P(s,t)),{ok:!0,data:F(s)}):null}async function Mt(e,t,n,r){if(t===`hidden`)return null;let i=await Pt(e,n);if(Z(i))return i.response;if(!i?.result.found||!i.result.node)return null;let a=t===`exists`?{predicate:t,pass:!0,selector:i.selector.raw,matches:1,selectorChain:[i.selector.raw]}:Lt(t,r,i.selector.raw,i.session,i.result.node);return a?(L(e.sessionStore,e.sessionName,e.req,a),{ok:!0,data:I(a)}):null}async function Nt(e){let t=G({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let n=Date.now(),r=await X(e,e.session,t);if(Z(r))return r.response;if(!r?.found)return null;let i={kind:`selector`,selector:t.raw,waitedMs:Date.now()-n,selectorChain:[t.raw]};L(e.sessionStore,e.sessionName,e.req,i);let a={ok:!0,data:i};return await B({req:e.req,logPath:e.logPath,session:e.session,device:e.device},a)}async function Pt(e,t){let n=e.sessionStore.get(e.sessionName),r=G({session:n,selectorExpression:t});if(!n||!r)return null;let i=await X(e,n,r);return Z(i)?i:i?{session:n,selector:r,result:i}:null}async function Ft(e,t,n){let r=await g(t.device,{command:`querySelector`,selectorKey:n.key,selectorValue:n.value,appBundleId:t.appBundleId},T({req:e.req,logPath:e.logPath,traceLogPath:t.trace?.outPath})),i=r.found===!0,a=Rt(r);return{found:i,...typeof r.text==`string`?{text:r.text}:{},...a?{node:a}:{}}}async function X(t,n,r){try{return await Ft(t,n,r)}catch(t){return K(t,{allowElementNotFound:!0})?null:{kind:`error`,response:{ok:!1,error:e(t)}}}}function Z(e){return e!==null&&`kind`in e&&e.kind===`error`}function It(e,t,n){if(!n.found||!n.node)return null;let r={target:{kind:`selector`,selector:t},node:n.node,selectorChain:[t]};return e===`attrs`?{kind:`attrs`,...r}:typeof n.text==`string`?{kind:`text`,...r,text:n.text}:null}function Lt(e,t,n,r,i){let a=re({predicate:e,node:i,nodes:[i],expectedText:t,platform:r.device.platform});return{predicate:e,pass:a.pass,selector:n,...e===`text`?{text:a.actualText}:{},selectorChain:[n]}}function Rt(e){let t=e.nodes;if(!Array.isArray(t))return;let n=t[0];if(!(!n||typeof n!=`object`))return n}function zt(e){let t=e.positionals?.[1]??``;if(t.startsWith(`@`)){let n=j(t);return n.ok?{ok:!0,target:{kind:`ref`,ref:n.ref,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(` `).trim():``},refGeneration:n.generation}:{ok:!1,response:n.response}}let n=e.positionals?.slice(1).join(` `).trim()??``;return n?{ok:!0,target:{kind:`selector`,selector:n}}:{ok:!1,response:y(`INVALID_ARGS`,`get requires @ref or selector expression`)}}function Bt(e,t){if(e.kind===`sleep`)return{kind:`sleep`,durationMs:e.durationMs};if(e.kind===`selector`)return{kind:`selector`,selector:e.selectorExpression,timeoutMs:e.timeoutMs};if(e.kind===`ref`){if(!t?.snapshot)throw new n(`INVALID_ARGS`,`Ref wait requires an existing snapshot in session.`);return{kind:`ref`,ref:e.rawRef,timeoutMs:e.timeoutMs}}if(e.kind===`stable`)return{kind:`stable`,quietMs:e.quietMs,timeoutMs:e.timeoutMs};if(!e.text)throw new n(`INVALID_ARGS`,`wait requires text`);return{kind:`text`,text:e.text,timeoutMs:e.timeoutMs}}async function Q(e){try{return{ok:!0,data:await e()}}catch(e){let t=r(e);return y(t.code,t.message,t.details)}}async function $(e,t,n){if(t.ok)return t;let r=e.sessionStore.get(e.sessionName);if(!r)return t;let i;try{i=await N(r)}catch{return t}return i?y(t.error.code,`${n} failed because ${Be(i)}.`,{...t.error.details??{},...i,blockedBy:`android_foreground_surface`,originalMessage:t.error.message}):t}function Vt(e){return e===`exists`||e===`wait`||e===`get_text`||e===`get_attrs`}export{k as C,O as S,Oe as _,q as a,we as b,G as c,Pe as d,Ne as f,M as g,ke as h,At as i,ze as l,Ae as m,Ot as n,rt as o,je as p,kt as r,K as s,Dt as t,Ve as u,A as v,D as w,Ce as x,De as y};
|
package/dist/src/selectors.d.ts
CHANGED
|
@@ -1,137 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
declare
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
enabled?: boolean;
|
|
41
|
-
selected?: boolean;
|
|
42
|
-
focused?: boolean;
|
|
43
|
-
visibleToUser?: boolean;
|
|
44
|
-
hittable?: boolean;
|
|
45
|
-
depth?: number;
|
|
46
|
-
parentIndex?: number;
|
|
47
|
-
pid?: number;
|
|
48
|
-
bundleId?: string;
|
|
49
|
-
appName?: string;
|
|
50
|
-
windowTitle?: string;
|
|
51
|
-
surface?: string;
|
|
52
|
-
hiddenContentAbove?: boolean;
|
|
53
|
-
hiddenContentBelow?: boolean;
|
|
54
|
-
interactionBlocked?: 'covered';
|
|
55
|
-
presentationHints?: string[];
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
declare type Rect = {
|
|
59
|
-
x: number;
|
|
60
|
-
y: number;
|
|
61
|
-
width: number;
|
|
62
|
-
height: number;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export declare function resolveSelectorChain(nodes: SnapshotState['nodes'], chain: SelectorChain, options: {
|
|
66
|
-
platform: Platform | PublicPlatform;
|
|
67
|
-
requireRect?: boolean;
|
|
68
|
-
requireUnique?: boolean;
|
|
69
|
-
disambiguateAmbiguous?: boolean;
|
|
70
|
-
}): SelectorResolution | null;
|
|
71
|
-
|
|
72
|
-
declare type Selector = {
|
|
73
|
-
raw: string;
|
|
74
|
-
terms: SelectorTerm[];
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export declare type SelectorChain = {
|
|
78
|
-
raw: string;
|
|
79
|
-
selectors: Selector[];
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export declare type SelectorDiagnostics = {
|
|
83
|
-
selector: string;
|
|
84
|
-
matches: number;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
declare type SelectorKey = 'id' | 'role' | 'text' | 'label' | 'value' | 'appname' | 'windowtitle' | 'visible' | 'hidden' | 'editable' | 'selected' | 'enabled' | 'hittable';
|
|
88
|
-
|
|
89
|
-
declare type SelectorResolution = {
|
|
90
|
-
node: SnapshotNode;
|
|
91
|
-
selector: Selector;
|
|
92
|
-
selectorIndex: number;
|
|
93
|
-
matches: number;
|
|
94
|
-
diagnostics: SelectorDiagnostics[];
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
declare type SelectorTerm = {
|
|
98
|
-
key: SelectorKey;
|
|
99
|
-
value: string | boolean;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
declare type SnapshotBackend = 'xctest' | 'android' | 'macos-helper' | 'linux-atspi' | 'web';
|
|
103
|
-
|
|
104
|
-
declare type SnapshotNode = RawSnapshotNode & {
|
|
105
|
-
ref: string;
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Structured quality verdict computed once by the iOS runner's snapshot capture plan.
|
|
110
|
-
* The daemon renders it; it never re-derives degradation from node shapes.
|
|
111
|
-
*
|
|
112
|
-
* Defined here (the foundational snapshot type module) rather than in
|
|
113
|
-
* snapshot-quality.ts so SnapshotNode can reference it without a cyclic import;
|
|
114
|
-
* snapshot-quality.ts (the validation logic) re-exports it for existing callers.
|
|
115
|
-
*/
|
|
116
|
-
declare type SnapshotQualityVerdict = {
|
|
117
|
-
state: 'healthy' | 'recovered' | 'sparse';
|
|
118
|
-
backend: 'tree' | 'queries' | 'private-ax';
|
|
119
|
-
reason?: string;
|
|
120
|
-
reasonCode?: 'ax-rejected' | 'sparse-tree' | 'budget' | 'no-nodes' | 'capture-failed';
|
|
121
|
-
effectiveDepth?: number;
|
|
122
|
-
collapsedLeafIndexes?: number[];
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
declare type SnapshotState = {
|
|
126
|
-
nodes: SnapshotNode[];
|
|
127
|
-
createdAt: number;
|
|
128
|
-
truncated?: boolean;
|
|
129
|
-
backend?: SnapshotBackend;
|
|
130
|
-
snapshotQuality?: SnapshotQualityVerdict;
|
|
131
|
-
comparisonSafe?: boolean;
|
|
132
|
-
presentationKey?: string;
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
export declare function tryParseSelectorChain(expression: string): SelectorChain | null;
|
|
136
|
-
|
|
137
|
-
export { }
|
|
1
|
+
import { S as SnapshotNode, V as PublicPlatform, w as SnapshotState, z as Platform } from "./sdk-contracts.js";
|
|
2
|
+
import { a as Selector, c as parseSelectorChain, l as tryParseSelectorChain, o as SelectorChain, s as isSelectorToken } from "./sdk-finders.js";
|
|
3
|
+
|
|
4
|
+
//#region src/daemon/selectors-resolve.d.ts
|
|
5
|
+
type SelectorDiagnostics = {
|
|
6
|
+
selector: string;
|
|
7
|
+
matches: number;
|
|
8
|
+
};
|
|
9
|
+
type SelectorResolution = {
|
|
10
|
+
node: SnapshotNode;
|
|
11
|
+
selector: Selector;
|
|
12
|
+
selectorIndex: number;
|
|
13
|
+
matches: number;
|
|
14
|
+
diagnostics: SelectorDiagnostics[];
|
|
15
|
+
};
|
|
16
|
+
declare function resolveSelectorChain(nodes: SnapshotState['nodes'], chain: SelectorChain, options: {
|
|
17
|
+
platform: Platform | PublicPlatform;
|
|
18
|
+
requireRect?: boolean;
|
|
19
|
+
requireUnique?: boolean;
|
|
20
|
+
disambiguateAmbiguous?: boolean;
|
|
21
|
+
}): SelectorResolution | null;
|
|
22
|
+
declare function findSelectorChainMatch(nodes: SnapshotState['nodes'], chain: SelectorChain, options: {
|
|
23
|
+
platform: Platform | PublicPlatform;
|
|
24
|
+
requireRect?: boolean;
|
|
25
|
+
}): {
|
|
26
|
+
selectorIndex: number;
|
|
27
|
+
selector: Selector;
|
|
28
|
+
matches: number;
|
|
29
|
+
diagnostics: SelectorDiagnostics[];
|
|
30
|
+
} | null;
|
|
31
|
+
declare function formatSelectorFailure(chain: SelectorChain, diagnostics: SelectorDiagnostics[], options: {
|
|
32
|
+
unique?: boolean;
|
|
33
|
+
}): string;
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/utils/selector-node.d.ts
|
|
36
|
+
declare function isNodeVisible(node: SnapshotNode): boolean;
|
|
37
|
+
declare function isNodeEditable(node: SnapshotNode, platform: Platform | PublicPlatform): boolean;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { type SelectorChain, type SelectorDiagnostics, findSelectorChainMatch, formatSelectorFailure, isNodeEditable, isNodeVisible, isSelectorToken, parseSelectorChain, resolveSelectorChain, tryParseSelectorChain };
|
package/dist/src/selectors.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{_ as e,g as t,y as n}from"./sdk-batch.js";import{c as r,s as i}from"./sdk-selectors.js";import{a,i as o,r as s}from"./selectors2.js";export{s as findSelectorChainMatch,o as formatSelectorFailure,i as isNodeEditable,r as isNodeVisible,t as isSelectorToken,e as parseSelectorChain,a as resolveSelectorChain,n as tryParseSelectorChain};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{C as e,N as t,R as n,c as r,d as i,s as a}from"./sdk-selectors.js";import{i as o}from"./sdk-finders.js";function s(e,t,n){return t.terms.every(t=>c(e,t,n))}function c(e,n,o){switch(n.key){case`id`:return l(e.identifier,String(n.value));case`role`:return l(t(e.type??``),String(n.value));case`label`:return l(e.label,String(n.value));case`value`:return l(e.value,String(n.value));case`text`:return l(i(e),String(n.value));case`appname`:return l(e.appName,String(n.value));case`windowtitle`:return l(e.windowTitle,String(n.value));case`visible`:return r(e)===!!n.value;case`hidden`:return!r(e)==!!n.value;case`editable`:return a(e,o)===!!n.value;case`selected`:return e.selected===!0==!!n.value;case`enabled`:return e.enabled!==!1==!!n.value;case`hittable`:return e.hittable===!0==!!n.value;default:return!1}}function l(e,t){return o(e??``)===o(t)}function u(e,t,n){let r=n.requireRect??!1,i=n.requireUnique??!0,a=[];for(let[o,s]of t.selectors.entries()){let t=h(e,s,n.platform,r);if(a.push({selector:s.raw,matches:t.count}),!(t.count===0||!t.firstNode)){if(i&&t.count!==1){if(!n.disambiguateAmbiguous||!t.disambiguated)continue;return{node:t.disambiguated,selector:s,selectorIndex:o,matches:t.count,diagnostics:a}}return{node:t.firstNode,selector:s,selectorIndex:o,matches:t.count,diagnostics:a}}}return null}function d(e,t,n){let r=n.requireRect??!1,i=[];for(let[a,o]of t.selectors.entries()){let t=_(e,o,n.platform,r);if(i.push({selector:o.raw,matches:t}),t>0)return{selectorIndex:a,selector:o,matches:t,diagnostics:i}}return null}const f=`Snapshot refs expire when the UI changes. Run snapshot -i and retry with a fresh @ref.`;function p(e){return e.some(e=>e.matches>1)?`Add more terms to disambiguate (e.g. role=button text="Sign in"), use an @ref from snapshot -i, or use find <text> --first/--last.`:`Selector text/label values match exactly (quote multi-word values: text="Sign in"). Run snapshot -i to see current elements and refs, or use find <text> for contains matching.`}function m(e,t,n){if(t.length===0)return`Selector did not match: ${e.raw}`;let r=t.map(e=>`${e.selector} -> ${e.matches}`).join(`, `);return n.unique??!0?`Selector did not resolve uniquely (${r})`:`Selector did not match (${r})`}function h(t,r,i,a){let o=0,c=null,l={best:null,bestVisible:!1,tie:!1},u,d=r=>(u??=n(t),e(r,t,u));for(let e of t)a&&!e.rect||s(e,r,i)&&(o+=1,c??=e,g(l,e,d));return{count:o,firstNode:c,disambiguated:l.tie?null:l.best}}function g(e,t,n){if(!e.best){e.best=t;return}e.bestVisible||=n(e.best);let r=n(t);if(r!==e.bestVisible){r&&(e.best=t,e.bestVisible=!0,e.tie=!1);return}let i=v(t,e.best);i>0?(e.best=t,e.tie=!1):i===0&&(e.tie=!0)}function _(e,t,n,r){let i=0;for(let a of e)r&&!a.rect||s(a,t,n)&&(i+=1);return i}function v(e,t){let n=e.depth??0,r=t.depth??0;if(n!==r)return n>r?1:-1;let i=y(e),a=y(t);return i===a?0:i<a?1:-1}function y(e){return e.rect?e.rect.width*e.rect.height:1/0}function b(e,n,a={}){let o=[],s=t(e.type??``),c=C(e.identifier),l=C(e.label),u=C(e.value),d=C(i(e)),f=a.action===`fill`;c&&o.push(`id=${S(c)}`),s&&l&&o.push(f?`role=${S(s)} label=${S(l)} editable=true`:`role=${S(s)} label=${S(l)}`),l&&o.push(f?`label=${S(l)} editable=true`:`label=${S(l)}`),u&&o.push(f?`value=${S(u)} editable=true`:`value=${S(u)}`),d&&d!==l&&d!==u&&o.push(f?`text=${S(d)} editable=true`:`text=${S(d)}`),s&&f&&!o.some(e=>e.includes(`editable=true`))&&o.push(`role=${S(s)} editable=true`);let p=x(o);return p.length===0&&s&&p.push(f?`role=${S(s)} editable=true`:`role=${S(s)}`),p.length===0&&r(e)&&p.push(`visible=true`),p}function x(e){return Array.from(new Set(e))}function S(e){return JSON.stringify(e)}function C(e){return e&&e.trim()||null}export{u as a,m as i,f as n,p as o,d as r,s,b as t};
|
package/dist/src/server.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import{SESSION_SURFACES as e,isCommandName as t,stringSchema as r,DEVICE_ROTATIONS as n,listMcpCommandMetadata as o,booleanSchema as i,BACK_MODES as s,looseObjectSchema as a}from"./2948.js";import{DEVICE_TARGETS as c,RESPONSE_LEVELS as u,jsonRpcRequestSchema as d,PLATFORMS as p}from"./6849.js";import{formatCliOutput as l}from"./cli-output.js";import{readVersion as f}from"./1404.js";function m(e){return{type:"number",...e?{description:e}:{}}}function h(e,t){return{type:"string",enum:e,...t?{description:t}:{}}}function g(e){return{type:"string",const:e}}function y(e,t=[],r){return{type:"object",...r?{description:r}:{},properties:e,...t.length>0?{required:t}:{}}}let b={type:"array",items:{type:"string"}},w=y({x:m(),y:m(),width:m(),height:m()},["x","y","width","height"]),v=y({x:m(),y:m()},["x","y"]),x=y({index:m(),ref:r("Stable snapshot ref such as e12."),type:r(),role:r(),subrole:r(),label:r(),value:r(),identifier:r(),rect:w,enabled:i(),selected:i(),focused:i(),visibleToUser:i(),hittable:i(),depth:m(),parentIndex:m(),pid:m(),bundleId:r(),appName:r(),windowTitle:r(),surface:r(),hiddenContentAbove:i(),hiddenContentBelow:i(),interactionBlocked:h(["covered"]),presentationHints:b},["index","ref"],"Resolved snapshot node for the matched element."),k=y({kind:g("ref"),ref:r()},["kind","ref"]),C=y({kind:g("selector"),selector:r()},["kind","selector"]);function _(e={}){let t=e.properties??{},n=e.required??[];return{type:"object",oneOf:[y({kind:g("point"),point:v,...t},["kind","point",...n]),y({kind:g("ref"),point:v,target:k,node:x,selectorChain:b,refLabel:r(),...t},["kind","target",...n]),y({kind:g("selector"),point:v,target:C,node:x,selectorChain:b,refLabel:r(),...t},["kind","point","target","node","selectorChain",...n])]}}let S=a("Raw backend result passthrough."),E={platform:h(p),target:h(c),device:r("Human-readable device name."),id:r("Stable device id."),kind:h(["simulator","emulator","device"])},A=["platform","target","device","id","kind"],j=y({success:i(),exitCode:m(),stdout:r(),stderr:r(),error:a("Normalized error detail when shutdown failed.")},["success","exitCode","stdout","stderr"]),O={press:_({properties:{backendResult:S,message:r()}}),fill:_({properties:{text:r("Text submitted to the field."),warning:r(),backendResult:S,message:r()},required:["text"]}),longpress:_({properties:{durationMs:m(),backendResult:S,message:r()}}),boot:y({...E,booted:{type:"boolean",const:!0}},[...A,"booted"]),shutdown:y({...E,shutdown:j},[...A,"shutdown"]),viewport:y({width:m(),height:m(),message:r()},["width","height","message"]),home:y({action:g("home"),message:r()},["action","message"]),back:y({action:g("back"),mode:h(s),message:r()},["action","mode","message"]),rotate:y({action:g("rotate"),orientation:h(n),message:r()},["action","orientation","message"]),"app-switcher":y({action:g("app-switcher"),message:r()},["action","message"]),clipboard:{type:"object",oneOf:[y({action:g("read"),text:r()},["action","text"]),y({action:g("write"),textLength:m(),message:r()},["action","textLength","message"])]},appstate:{type:"object",oneOf:[y({platform:h(["ios","macos"]),appName:r(),appBundleId:r(),source:g("session"),surface:h(e),device_udid:r("iOS only — the session device UDID."),ios_simulator_device_set:{type:["string","null"],description:"iOS only — the simulator set path, or null when unknown."}},["platform","appName","source","surface"]),y({platform:g("android"),package:r(),activity:r()},["platform","package","activity"])]},keyboard:y({platform:h(["android","ios"]),action:h(["status","dismiss","enter"]),visible:i(),wasVisible:i(),dismissed:i(),attempts:m(),inputType:r(),type:h(["text","number","email","phone","password","datetime","unknown"]),inputMethodPackage:r(),focusedPackage:r(),focusedResourceId:r(),inputOwner:h(["app","ime","unknown"]),message:r()},["platform","action"])},R=function(e={}){return{execute:async(r,n)=>{var o;if(!t(r))throw Error(`Unknown command tool: ${r}`);let i=!(o=n)||"object"!=typeof o||Array.isArray(o)?{client:{},outputFormat:"optimized"}:{client:function(e){let t=e.stateDir,r=e.includeCost,n=e.responseLevel,o={};if(void 0!==t&&("string"!=typeof t||0===t.length))throw Error("Expected stateDir to be a non-empty string.");if("string"==typeof t&&(o.stateDir=t),void 0!==r&&"boolean"!=typeof r)throw Error("Expected includeCost to be a boolean.");!0===r&&(o.cost=!0);let i=function(e){if(void 0!==e){if("string"!=typeof e||!u.includes(e))throw Error("Expected responseLevel to be one of 'digest', 'default', or 'full'.");return e}}(n);return void 0!==i&&(o.responseLevel=i),o}(o),outputFormat:function(e){if(void 0===e)return"optimized";if("optimized"!==e&&"json"!==e)throw Error('Expected mcpOutputFormat to be "optimized" or "json".');return e}(o.mcpOutputFormat)},s=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;let{stateDir:t,mcpOutputFormat:r,includeCost:n,responseLevel:o,...i}=e;return i}(n),a=await N(e,i.client),c=await (e.runCommand??L)(a,r,s);return{isError:!1,structuredContent:c,content:[{type:"text",text:function(e){if("json"===e.outputFormat||void 0!==e.responseLevel&&"default"!==e.responseLevel)return P(e.result);let t=l({name:e.name,input:e.input,result:e.result});return"string"==typeof t?.text?t.text:P(t?.data??e.result)}({name:r,input:s,result:c,outputFormat:i.outputFormat,responseLevel:i.client.responseLevel})}]}}}}();async function N(e,t){if(e.createClient)return await e.createClient(t);let{createAgentDeviceClient:r}=await import("./495.js");return r(t)}async function L(e,t,r){let n=await import("./command-surface.js");return await n.runCommand(e,t,r)}function P(e){return"string"==typeof e?e:JSON.stringify(e,null,2)}async function M(e){if("2.0"!==e.jsonrpc||"string"!=typeof e.method)return U(e.id??null,-32600,"Invalid JSON-RPC request.");if(void 0===e.id)return null;try{var t,r;return t=e.id,r=await K(e.method,e.params),{jsonrpc:"2.0",id:t,result:r}}catch(t){if(t instanceof F)return U(e.id,-32601,t.message);return U(e.id,-32602,t instanceof Error?t.message:String(t))}}async function K(e,t){switch(e){case"initialize":return{protocolVersion:"2025-11-25",capabilities:{tools:{}},serverInfo:{name:"agent-device",version:f()}};case"ping":return{};case"tools/list":return{tools:o().map(e=>{var t;let r=e.name in O?O[e.name]:void 0;return{name:e.name,description:e.description,inputSchema:{...t=e.inputSchema,properties:{...t.properties,stateDir:{type:"string",description:"Agent-device state directory."},mcpOutputFormat:{type:"string",enum:["optimized","json"],description:"MCP text content format. Defaults to optimized agent-friendly text; use json for JSON text. Structured content is always returned separately."},includeCost:{type:"boolean",description:"Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged."},responseLevel:{type:"string",enum:["digest","default","full"],description:"Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged."}}},...r?{outputSchema:r}:{}}})};case"tools/call":return await D(t);default:throw new F(`Unsupported MCP method: ${e}`)}}async function D(e){let t=function(e){if(!e||"object"!=typeof e||Array.isArray(e))throw Error("Expected object parameters.");return e}(e),r=function(e,t){let r=e[t];if("string"!=typeof r||0===r.length)throw Error(`Expected ${t} to be a non-empty string.`);return r}(t,"name");try{return await R.execute(r,t.arguments)}catch(e){return function(e,t=!1){return{isError:t,content:[{type:"text",text:e}]}}(e instanceof Error?e.message:String(e),!0)}}function U(e,t,r){return{jsonrpc:"2.0",id:e,error:{code:t,message:r}}}class F extends Error{}async function I(){let e=function(e={}){let t=e.handlePayload??z,r=e.write??$,n=Promise.resolve();return{push:e=>{var o;let i=Array.isArray(o=e)?1===o.length?q(o[0]):null:q(o);n=n.then(async()=>{let n=await t(e);n&&r(n)}).catch(e=>{r({jsonrpc:"2.0",id:i,error:{code:-32603,message:e instanceof Error?e.message:String(e)}})})},idle:async()=>{await n}}}(),t=new T(t=>{e.push(t)});process.stdin.setEncoding("utf8"),process.stdin.on("data",e=>{try{t.push(e)}catch(e){$({jsonrpc:"2.0",id:null,error:{code:-32700,message:e instanceof Error?e.message:String(e)}})}}),await new Promise(e=>{process.stdin.on("end",e),process.stdin.on("close",e),process.stdin.resume()}),await e.idle()}function z(e){return Array.isArray(e)?H(e):J(e)}async function H(e){let t=[];for(let n of e){var r;t.push(...(r=await J(n))?[r]:[])}return t.length>0?t:null}async function J(e){let t;try{t=d.parse(e)}catch{return{jsonrpc:"2.0",id:q(e),error:{code:-32600,message:"Invalid JSON-RPC request."}}}return M(t)}function q(e){if(e&&"object"==typeof e&&!Array.isArray(e)){let t=e.id;if("string"==typeof t||"number"==typeof t||null===t)return t}return null}class T{buffer="";sink;constructor(e){this.sink=e}push(e){for(this.buffer+=e;;){let e=this.tryReadLineMessage();if(void 0!==e){this.emit(e);continue}break}}tryReadLineMessage(){let e=this.buffer.indexOf("\n");if(-1===e)return;let t=this.buffer.slice(0,e).trim();return this.buffer=this.buffer.slice(e+1),t.length>0?t:void 0}emit(e){this.sink(JSON.parse(e))}}function $(e){process.stdout.write(`${JSON.stringify(e)}
|
|
2
|
-
`)}
|
|
1
|
+
import{B as e,F as t,c as n,n as r,o as i,s as a}from"./sdk-contracts.js";import{n as o}from"./version.js";import{Wt as s,t as c}from"./device-rotation.js";import{A as l,j as u,k as d,s as f}from"./registry.js";import{i as p,n as m}from"./command-metadata.js";import{t as ee}from"./cli-output.js";const h=[`simulator`,`emulator`,`device`];function g(e){return{type:`number`,...e?{description:e}:{}}}function _(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function v(e){return{type:`string`,const:e}}function y(e,t=[],n){return{type:`object`,...n?{description:n}:{},properties:e,...t.length>0?{required:t}:{}}}const te={type:`array`,items:{type:`string`}};function b(e={}){let t=e.properties??{},n=e.required??[];return y({targetKind:_([`point`,`ref`,`selector`],`Resolved interaction target kind.`),x:g(`Resolved interaction x coordinate when available.`),y:g(`Resolved interaction y coordinate when available.`),referenceWidth:g(`Reference frame width for visualizing the interaction point.`),referenceHeight:g(`Reference frame height for visualizing the interaction point.`),ref:u(`Snapshot ref without the @ prefix when the target was an @ref.`),selector:u(`Selector expression when the target was a selector.`),selectorChain:te,refLabel:u(),targetHittable:d(),hint:u(),warning:u(),message:u(),evidence:x,...t},[`targetKind`,...n])}const x=y({foregroundApp:u(`Foreground app bundle id or name, when the capture carries it.`),nodeCount:g(`Node count in the post-action interactive-only capture.`),interactiveNodeCount:g(`Subset of nodeCount the platform reports as hittable.`),digest:u(`Order-independent digest of the post-action node multiset.`),changedFromBefore:d(`Whether the post-action digest differs from the pre-action capture digest. false is evidence, not failure.`)},[`nodeCount`,`interactiveNodeCount`,`digest`,`changedFromBefore`]),S=y({settled:d(`Whether the UI held the quiet window before the deadline. false is advisory, not failure.`),waitedMs:g(),captures:g(),quietMs:g(),timeoutMs:g(),refsGeneration:g(`Snapshot generation of the stored settled tree; refs on added diff lines were minted from it.`),refs:{type:`array`,items:y({ref:u(`Plain ref body (e12) minted from the stored settled tree.`)},[`ref`])},diff:y({summary:y({additions:g(),removals:g(),unchanged:g()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:y({kind:_([`added`,`removed`]),text:u(),ref:u(`Plain ref body (e12) for added lines.`)},[`kind`,`text`])},truncated:d(`Lines were capped to the response bound.`)},[`summary`,`lines`],`Settled diff vs the pre-action tree (changed lines only).`),hint:u()},[`settled`,`waitedMs`,`captures`,`quietMs`,`timeoutMs`]),C={platform:_(n),target:_(a),device:u(`Human-readable device name.`),id:u(`Stable device id.`),kind:_(h)},w=[`platform`,`target`,`device`,`id`,`kind`],ne=y({success:d(),exitCode:g(),stdout:u(),stderr:u(),error:l(`Normalized error detail when shutdown failed.`)},[`success`,`exitCode`,`stdout`,`stderr`]),T={press:b({properties:{evidence:x,settle:S,button:_([`secondary`,`middle`])}}),fill:b({properties:{text:u(`Text submitted to the field.`),delayMs:g(`Delay between typed characters in milliseconds.`),evidence:x,settle:S},required:[`text`]}),longpress:b({properties:{durationMs:g(),settle:S,gesture:v(`longpress`)}}),boot:y({...C,booted:{type:`boolean`,const:!0}},[...w,`booted`]),shutdown:y({...C,shutdown:ne},[...w,`shutdown`]),viewport:y({width:g(),height:g(),message:u()},[`width`,`height`,`message`]),home:y({action:v(`home`),message:u()},[`action`,`message`]),back:y({action:v(`back`),mode:_(f),message:u()},[`action`,`mode`,`message`]),rotate:y({action:v(`rotate`),orientation:_(c),message:u()},[`action`,`orientation`,`message`]),"app-switcher":y({action:v(`app-switcher`),message:u()},[`action`,`message`]),clipboard:{type:`object`,oneOf:[y({action:v(`read`),text:u()},[`action`,`text`]),y({action:v(`write`),textLength:g(),message:u()},[`action`,`textLength`,`message`])]},appstate:{type:`object`,oneOf:[y({platform:_([`ios`,`macos`]),appName:u(),appBundleId:u(),source:v(`session`),surface:_(s),device_udid:u(`iOS only — the session device UDID.`),ios_simulator_device_set:{type:[`string`,`null`],description:`iOS only — the simulator set path, or null when unknown.`}},[`platform`,`appName`,`source`,`surface`]),y({platform:v(`android`),package:u(),activity:u()},[`platform`,`package`,`activity`])]},keyboard:y({platform:_([`android`,`ios`]),action:_([`status`,`dismiss`,`enter`]),visible:d(),wasVisible:d(),dismissed:d(),attempts:g(),inputType:u(),type:_([`text`,`number`,`email`,`phone`,`password`,`datetime`,`unknown`]),inputMethodPackage:u(),focusedPackage:u(),focusedResourceId:u(),inputOwner:_([`app`,`ime`,`unknown`]),message:u()},[`platform`,`action`])};function re(){return p().map(e=>{let t=e.name in T?T[e.name]:void 0;return{name:e.name,description:e.description,inputSchema:se(e.inputSchema),...t?{outputSchema:t}:{}}})}function ie(e={}){let n=new Map;return{execute:async(r,i)=>{if(!m(r))throw new t(`INVALID_ARGS`,`Unknown command tool: ${r}`);let a=V(i),o=G(i),s=D(a,o),c=N(r,o,n.get(s)),l=await z(e,a.client),u=await(e.runCommand??B)(l,r,c);return O(n,s,r,u),{isError:!1,structuredContent:u,content:[{type:`text`,text:K({name:r,input:o,result:u,outputFormat:a.outputFormat,responseLevel:a.client.responseLevel})}]}}}}const ae=new Set([`snapshot`,`find`]),oe=new Set([`press`,`click`,`fill`,`longpress`]),E=new Set([`press`,`click`,`fill`,`longpress`,`get`]);function D(e,t){let n=L(t)?.session,r=typeof n==`string`&&n.length>0?n:`default`;return`${e.client.stateDir??``}\u0000${r}`}function O(e,t,n,r){if(oe.has(n)){k(e,t,r);return}if(!ae.has(n))return;let i=L(r),a=i?.refsGeneration;if(i===void 0||typeof a!=`number`){e.delete(t);return}let o=j(i);if(o.length===0)return;let s=e.get(t)??new Map;e.set(t,s),A(s,o,a)}function k(e,t,n){let r=L(L(n)?.settle);if(!r)return;let i=r?.refsGeneration;if(typeof i!=`number`)return;let a=L(r?.diff)?.lines,o=[];if(M(a,o),M(r.refs,o),o.length===0)return;let s=e.get(t)??new Map;e.set(t,s),A(s,o,i)}function A(e,t,n){for(let r of t)e.delete(r),e.set(r,n);for(;e.size>1e3;){let t=e.keys().next().value;if(t===void 0)break;e.delete(t)}}function j(e){let t=[];return typeof e.ref==`string`&&e.ref.startsWith(`@`)&&t.push(e.ref.slice(1)),M(e.nodes,t),M(e.refs,t),t}function M(e,t){if(Array.isArray(e))for(let n of e){let e=L(n)?.ref;typeof e==`string`&&e.length>0&&t.push(e)}}function N(e,t,n){if(n===void 0||n.size===0)return t;let r=L(t);return r?e===`wait`?P(r,n)??t:E.has(e)?F(r,n)??t:t:t}function P(e,t){if(typeof e.ref!=`string`)return;let n=I(e.ref,t);return n===e.ref?void 0:{...e,ref:n}}function F(e,t){let n=L(e.target);if(n?.kind!==`ref`||typeof n.ref!=`string`)return;let r=I(n.ref,t);return r===n.ref?void 0:{...e,target:{...n,ref:r}}}function I(e,t){if(!e.startsWith(`@`)||e.includes(`~`))return e;let n=t.get(e.slice(1));return n===void 0?e:`${e}~s${n}`}function L(e){if(!(!e||typeof e!=`object`||Array.isArray(e)))return e}const R=ie();async function z(e,t){if(e.createClient)return await e.createClient(t);let{createAgentDeviceClient:n}=await import(`./client.js`).then(e=>e.t);return n(t)}async function B(e,t,n){return await(await import(`./command-surface.js`).then(e=>e.t)).runCommand(e,t,n)}function V(e){if(!e||typeof e!=`object`||Array.isArray(e))return{client:{},outputFormat:`optimized`};let t=e;return{client:H(t),outputFormat:W(t.mcpOutputFormat)}}function H(e){let n=e.stateDir,r=e.includeCost,i=e.responseLevel,a={};if(n!==void 0&&(typeof n!=`string`||n.length===0))throw new t(`INVALID_ARGS`,`Expected stateDir to be a non-empty string.`);if(typeof n==`string`&&(a.stateDir=n),r!==void 0&&typeof r!=`boolean`)throw new t(`INVALID_ARGS`,`Expected includeCost to be a boolean.`);r===!0&&(a.cost=!0);let o=U(i);return o!==void 0&&(a.responseLevel=o),a}function U(e){if(e!==void 0){if(typeof e!=`string`||!r.includes(e))throw new t(`INVALID_ARGS`,`Expected responseLevel to be one of 'digest', 'default', or 'full'.`);return e}}function W(e){if(e===void 0)return`optimized`;if(e!==`optimized`&&e!==`json`)throw new t(`INVALID_ARGS`,`Expected mcpOutputFormat to be "optimized" or "json".`);return e}function G(e){if(!e||typeof e!=`object`||Array.isArray(e))return e;let{stateDir:t,mcpOutputFormat:n,includeCost:r,responseLevel:i,...a}=e;return a}function se(e){return{...e,properties:{...e.properties,stateDir:{type:`string`,description:`Agent-device state directory.`},mcpOutputFormat:{type:`string`,enum:[`optimized`,`json`],description:`MCP text content format. Defaults to optimized agent-friendly text; use json for JSON text. Structured content is always returned separately.`},includeCost:{type:`boolean`,description:`Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged.`},responseLevel:{type:`string`,enum:[`digest`,`default`,`full`],description:`Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged.`}}}}function K(e){if(e.outputFormat===`json`||e.responseLevel!==void 0&&e.responseLevel!=="default")return q(e.result);let t=ee({name:e.name,input:e.input,result:e.result});return typeof t?.text==`string`?t.text:q(t?.data??e.result)}function q(e){return typeof e==`string`?e:JSON.stringify(e,null,2)}async function ce(e){if(e.jsonrpc!==`2.0`||typeof e.method!=`string`)return J(e.id??null,-32600,`Invalid JSON-RPC request.`);if(e.id===void 0)return null;try{return me(e.id,await le(e.method,e.params))}catch(t){return t instanceof Y?J(e.id,-32601,t.message):J(e.id,-32602,t instanceof Error?t.message:String(t))}}async function le(e,t){switch(e){case`initialize`:return{protocolVersion:fe(t),capabilities:{tools:{}},serverInfo:{name:`agent-device`,version:o()}};case`ping`:return{};case`tools/list`:return{tools:re()};case`tools/call`:return await ue(t);default:throw new Y(`Unsupported MCP method: ${e}`)}}async function ue(e){let t=he(e),n=ge(t,`name`);try{return await R.execute(n,t.arguments)}catch(e){return pe(de(e),!0)}}function de(t){let n=e(t),r=[`Error (${n.code}): ${n.message}`];return n.hint&&r.push(`Hint: ${n.hint}`),n.supportedOn&&r.push(`Supported on: ${n.supportedOn}`),r.join(`
|
|
2
|
+
`)}function fe(e){return`2025-11-25`}function pe(e,t=!1){return{isError:t,content:[{type:`text`,text:e}]}}function me(e,t){return{jsonrpc:`2.0`,id:e,result:t}}function J(e,t,n){return{jsonrpc:`2.0`,id:e,error:{code:t,message:n}}}function he(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Expected object parameters.`);return e}function ge(e,n){let r=e[n];if(typeof r!=`string`||r.length===0)throw new t(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}var Y=class extends Error{};async function _e(){let e=ve(),t=new Se(t=>{e.push(t)});process.stdin.setEncoding(`utf8`),process.stdin.on(`data`,e=>{try{t.push(e)}catch(e){$({jsonrpc:`2.0`,id:null,error:{code:-32700,message:e instanceof Error?e.message:String(e)}})}}),await new Promise(e=>{process.stdin.on(`end`,e),process.stdin.on(`close`,e),process.stdin.resume()}),await e.idle()}function ve(e={}){let t=e.handlePayload??ye,n=e.write??$,r=Promise.resolve();return{push:e=>{let i=xe(e);r=r.then(async()=>{let r=await t(e);r&&n(r)}).catch(e=>{n({jsonrpc:`2.0`,id:i,error:{code:-32603,message:e instanceof Error?e.message:String(e)}})})},idle:async()=>{await r}}}function ye(e){return Array.isArray(e)?X(e):Z(e)}async function X(e){let t=[];for(let n of e)t.push(...Ce(await Z(n)));return t.length>0?t:null}async function Z(e){let t;try{t=i.parse(e)}catch{return be(Q(e))}return ce(t)}function be(e){return{jsonrpc:`2.0`,id:e,error:{code:-32600,message:`Invalid JSON-RPC request.`}}}function xe(e){return Array.isArray(e)?e.length===1?Q(e[0]):null:Q(e)}function Q(e){if(e&&typeof e==`object`&&!Array.isArray(e)){let t=e.id;if(typeof t==`string`||typeof t==`number`||t===null)return t}return null}var Se=class{buffer=``;sink;constructor(e){this.sink=e}push(e){for(this.buffer+=e;;){let e=this.tryReadLineMessage();if(e!==void 0){this.emit(e);continue}break}}tryReadLineMessage(){let e=this.buffer.indexOf(`
|
|
3
|
+
`);if(e===-1)return;let t=this.buffer.slice(0,e).trim();return this.buffer=this.buffer.slice(e+1),t.length>0?t:void 0}emit(e){this.sink(JSON.parse(e))}};function Ce(e){return e?[e]:[]}function $(e){process.stdout.write(`${JSON.stringify(e)}\n`)}export{_e as runAgentDeviceMcpServer};
|