agent-device 0.19.0 → 0.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +5 -1
  2. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.apk +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.19.0.manifest.json → agent-device-android-multitouch-helper-0.19.2.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.19.0.apk → agent-device-android-snapshot-helper-0.19.2.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.2.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.19.0.manifest.json → agent-device-android-snapshot-helper-0.19.2.manifest.json} +6 -6
  8. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +24 -7
  9. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +506 -119
  10. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +153 -48
  11. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +172 -0
  12. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +76 -5
  13. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +60 -52
  14. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +159 -56
  15. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +142 -0
  16. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +16 -14
  17. package/dist/src/android-adb.d.ts +1 -2
  18. package/dist/src/android-adb.js +1 -1
  19. package/dist/src/android-input-ownership.js +6 -0
  20. package/dist/src/android.js +1 -1
  21. package/dist/src/app-lifecycle.js +3 -3
  22. package/dist/src/apple-runner-options.js +1 -1
  23. package/dist/src/apps.js +5 -5
  24. package/dist/src/cli-help.js +149 -37
  25. package/dist/src/cli-runner.js +1 -1
  26. package/dist/src/cli.js +11 -11
  27. package/dist/src/client.js +2 -2
  28. package/dist/src/command-metadata.js +1 -1
  29. package/dist/src/command-schema.js +3 -3
  30. package/dist/src/device-input-state.js +2 -2
  31. package/dist/src/devices2.js +1 -1
  32. package/dist/src/find.js +1 -1
  33. package/dist/src/generic.js +1 -1
  34. package/dist/src/index.d.ts +224 -20
  35. package/dist/src/input-actions.js +3 -3
  36. package/dist/src/interaction-snapshot.js +1 -1
  37. package/dist/src/interaction.js +1 -1
  38. package/dist/src/interactor.js +2 -2
  39. package/dist/src/internal/bin.js +1 -1
  40. package/dist/src/internal/daemon.js +17 -15
  41. package/dist/src/lease.js +1 -1
  42. package/dist/src/linux.js +1 -1
  43. package/dist/src/metro.d.ts +0 -1
  44. package/dist/src/notifications.js +1 -1
  45. package/dist/src/points.js +1 -1
  46. package/dist/src/project-runtime.js +1 -1
  47. package/dist/src/providers.js +1 -1
  48. package/dist/src/react-native.js +1 -1
  49. package/dist/src/record-trace-recording.js +2 -2
  50. package/dist/src/record-trace.js +1 -1
  51. package/dist/src/registry.js +24 -23
  52. package/dist/src/reporting.js +3 -3
  53. package/dist/src/runner-client.js +1 -1
  54. package/dist/src/runtime.js +2 -2
  55. package/dist/src/sdk-android-adb.d.ts +2 -2
  56. package/dist/src/sdk-batch-runner.d.ts +0 -1
  57. package/dist/src/sdk-batch.js +2 -2
  58. package/dist/src/sdk-finders.d.ts +1 -2
  59. package/dist/src/sdk-finders.js +1 -1
  60. package/dist/src/sdk-io.d.ts +0 -1
  61. package/dist/src/sdk-remote-config.d.ts +1 -2
  62. package/dist/src/sdk-remote-config.js +1 -1
  63. package/dist/src/sdk-selectors.js +1 -1
  64. package/dist/src/selector-runtime.js +1 -1
  65. package/dist/src/selectors.d.ts +0 -1
  66. package/dist/src/selectors.js +1 -1
  67. package/dist/src/selectors2.js +1 -1
  68. package/dist/src/server.js +3 -3
  69. package/dist/src/session.js +10 -10
  70. package/dist/src/simctl.js +1 -1
  71. package/dist/src/simulator.js +1 -1
  72. package/dist/src/snapshot-diagnostics.js +2 -2
  73. package/dist/src/snapshot-helper.js +4 -4
  74. package/dist/src/snapshot-quality.js +1 -1
  75. package/dist/src/snapshot2.js +2 -2
  76. package/dist/src/tv-remote.js +14 -0
  77. package/dist/src/version.js +1 -1
  78. package/dist/src/web.js +1 -1
  79. package/package.json +5 -4
  80. package/server.json +2 -2
  81. package/skills/agent-device/SKILL.md +8 -7
  82. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.0.apk +0 -0
  83. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.0.apk.sha256 +0 -1
  84. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.0.apk.sha256 +0 -1
  85. package/dist/src/device-rotation.js +0 -14
  86. package/dist/src/logcat.js +0 -6
@@ -4,7 +4,6 @@ import { t as BatchRunResult } from "./sdk-batch-runner.js";
4
4
  import { r as FindLocator } from "./sdk-finders.js";
5
5
  import { p as createLocalArtifactAdapter } from "./sdk-io.js";
6
6
  import { a as PrepareMetroRuntimeResult, c as MetroBridgeScope, i as MetroPrepareKind, o as ReloadMetroResult, r as RemoteConnectionProfileFields, t as CloudProviderProfileFields } from "./sdk-remote-config.js";
7
-
8
7
  //#region src/platforms/android/snapshot-helper-types.d.ts
9
8
  type AndroidSnapshotHelperTransport = 'instrumentation' | 'persistent-session';
10
9
  type AndroidSnapshotCaptureMode = 'interactive-windows' | 'active-window';
@@ -81,10 +80,60 @@ type ClickButton = (typeof CLICK_BUTTONS)[number];
81
80
  declare const RECORDING_EXPORT_QUALITIES: readonly ['medium', 'high'];
82
81
  type RecordingExportQuality = (typeof RECORDING_EXPORT_QUALITIES)[number];
83
82
  //#endregion
83
+ //#region src/core/recording-scope.d.ts
84
+ declare const RECORDING_SCOPE_VALUES: readonly ['app', 'device', 'system'];
85
+ type RecordingScope = (typeof RECORDING_SCOPE_VALUES)[number];
86
+ //#endregion
84
87
  //#region src/core/device-rotation.d.ts
85
88
  declare const DEVICE_ROTATIONS: readonly ['portrait', 'portrait-upside-down', 'landscape-left', 'landscape-right'];
86
89
  type DeviceRotation = (typeof DEVICE_ROTATIONS)[number];
87
90
  //#endregion
91
+ //#region src/core/tv-remote.d.ts
92
+ declare const TV_REMOTE_BUTTON_DEFINITIONS: {
93
+ readonly up: {
94
+ readonly aliases: readonly [];
95
+ readonly androidKeyevent: 'KEYCODE_DPAD_UP';
96
+ readonly appleRemoteButton: 'up';
97
+ };
98
+ readonly down: {
99
+ readonly aliases: readonly [];
100
+ readonly androidKeyevent: 'KEYCODE_DPAD_DOWN';
101
+ readonly appleRemoteButton: 'down';
102
+ };
103
+ readonly left: {
104
+ readonly aliases: readonly [];
105
+ readonly androidKeyevent: 'KEYCODE_DPAD_LEFT';
106
+ readonly appleRemoteButton: 'left';
107
+ };
108
+ readonly right: {
109
+ readonly aliases: readonly [];
110
+ readonly androidKeyevent: 'KEYCODE_DPAD_RIGHT';
111
+ readonly appleRemoteButton: 'right';
112
+ };
113
+ readonly select: {
114
+ readonly aliases: readonly ["ok", "center", "enter"];
115
+ readonly androidKeyevent: 'KEYCODE_DPAD_CENTER';
116
+ readonly appleRemoteButton: 'select';
117
+ };
118
+ readonly menu: {
119
+ readonly aliases: readonly [];
120
+ readonly androidKeyevent: 'KEYCODE_MENU';
121
+ readonly appleRemoteButton: 'menu';
122
+ };
123
+ readonly home: {
124
+ readonly aliases: readonly [];
125
+ readonly androidKeyevent: 'KEYCODE_HOME';
126
+ readonly appleRemoteButton: 'home';
127
+ };
128
+ readonly back: {
129
+ readonly aliases: readonly [];
130
+ readonly androidKeyevent: 'KEYCODE_BACK';
131
+ readonly appleRemoteButton: 'menu';
132
+ };
133
+ };
134
+ declare const TV_REMOTE_BUTTONS: (keyof typeof TV_REMOTE_BUTTON_DEFINITIONS)[];
135
+ type TvRemoteButton = (typeof TV_REMOTE_BUTTONS)[number];
136
+ //#endregion
88
137
  //#region src/core/scroll-gesture.d.ts
89
138
  declare const SCROLL_DIRECTIONS: readonly ['up', 'down', 'left', 'right'];
90
139
  type ScrollDirection = (typeof SCROLL_DIRECTIONS)[number];
@@ -106,6 +155,13 @@ type TransformGestureParams = {
106
155
  declare const ALERT_ACTIONS: readonly ['get', 'accept', 'dismiss', 'wait'];
107
156
  type AlertAction = (typeof ALERT_ACTIONS)[number];
108
157
  //#endregion
158
+ //#region src/contracts/json.d.ts
159
+ type JsonPrimitive = string | number | boolean | null;
160
+ type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
161
+ type JsonObject = {
162
+ [key: string]: JsonValue;
163
+ };
164
+ //#endregion
109
165
  //#region src/core/session-surface.d.ts
110
166
  declare const SESSION_SURFACES: readonly ['app', 'frontmost-app', 'desktop', 'menubar'];
111
167
  type SessionSurface = (typeof SESSION_SURFACES)[number];
@@ -113,6 +169,11 @@ type SessionSurface = (typeof SESSION_SURFACES)[number];
113
169
  //#region src/utils/screenshot-result.d.ts
114
170
  type ScreenshotResultData = {
115
171
  path?: string;
172
+ width?: number;
173
+ height?: number;
174
+ logicalWidth?: number;
175
+ logicalHeight?: number;
176
+ pixelDensity?: number;
116
177
  overlayRefs?: ScreenshotOverlayRef[];
117
178
  };
118
179
  //#endregion
@@ -180,6 +241,15 @@ type SettleDiffLine = {
180
241
  */
181
242
  ref?: string;
182
243
  };
244
+ /**
245
+ * One still-present, actionable element on the settled tree, surfaced by the
246
+ * unchanged-interactive tail (see `SettleObservation.tail`).
247
+ */
248
+ type SettleTailEntry = {
249
+ ref: string;
250
+ role: string;
251
+ label?: string;
252
+ };
183
253
  type SettleObservation = {
184
254
  settled: boolean;
185
255
  waitedMs: number;
@@ -202,15 +272,33 @@ type SettleObservation = {
202
272
  refs?: Array<{
203
273
  ref: string;
204
274
  }>;
275
+ /** Present only for `settled: true` observations that stored the settled tree. */
205
276
  diff?: {
206
277
  summary: {
207
278
  additions: number;
208
279
  removals: number;
209
280
  unchanged: number;
210
281
  };
211
- lines: SettleDiffLine[]; /** Present (true) when lines were capped to the response bound. */
282
+ lines: SettleDiffLine[];
283
+ /** Present (true) when lines were capped to the response bound. */
212
284
  truncated?: boolean;
213
285
  };
286
+ /**
287
+ * Unchanged interactive refs tail: benchmarks (July 2026) showed 27% of
288
+ * `--settle` actions were followed by a fallback `snapshot -i` because a
289
+ * change-only diff omits refs for elements that did not change — after a
290
+ * modal dismiss the diff shows only removals, and the next button to press
291
+ * (already on screen, untouched) is absent from the response. `tail` lists
292
+ * the settled tree's remaining hittable, uncovered interactive elements so
293
+ * the response stays actionable without that extra round trip. Attached
294
+ * ONLY when `diff` carries zero added-line refs (the modal-dismiss/
295
+ * toast-only signature) — a diff with fresh added refs already hands the
296
+ * next target, so the tail would be pure byte cost. Refs already present on
297
+ * `diff`'s added lines are excluded. Capped; `tailTruncated` marks when
298
+ * candidates exceeded the cap.
299
+ */
300
+ tail?: SettleTailEntry[];
301
+ tailTruncated?: true;
214
302
  hint?: string;
215
303
  };
216
304
  type PressCommandResult = ResolvedInteractionTarget & {
@@ -272,10 +360,13 @@ type PerfKind = (typeof PERF_KIND_VALUES)[number];
272
360
  */
273
361
  type BootCommandResult = {
274
362
  platform: PublicPlatform;
275
- target: DeviceTarget; /** Human-readable device name (`device.name`). */
276
- device: string; /** Stable device id (`device.id`). */
363
+ target: DeviceTarget;
364
+ /** Human-readable device name (`device.name`). */
365
+ device: string;
366
+ /** Stable device id (`device.id`). */
277
367
  id: string;
278
- kind: DeviceKind; /** Always `true` on the success path. */
368
+ kind: DeviceKind;
369
+ /** Always `true` on the success path. */
279
370
  booted: true;
280
371
  /**
281
372
  * Additive Apple-OS discriminant (`device.appleOs`): iPhone/iPad/tvOS/visionOS/macOS.
@@ -293,8 +384,10 @@ type BootCommandResult = {
293
384
  */
294
385
  type ShutdownCommandResult = {
295
386
  platform: PublicPlatform;
296
- target: DeviceTarget; /** Human-readable device name (`device.name`). */
297
- device: string; /** Stable device id (`device.id`). */
387
+ target: DeviceTarget;
388
+ /** Human-readable device name (`device.name`). */
389
+ device: string;
390
+ /** Stable device id (`device.id`). */
298
391
  id: string;
299
392
  kind: DeviceKind;
300
393
  shutdown: TargetShutdownResult;
@@ -352,6 +445,13 @@ type AppSwitcherCommandResult = {
352
445
  action: 'app-switcher';
353
446
  message: string;
354
447
  };
448
+ /** `tv-remote` — `{ action: 'tv-remote', button, durationMs?, message }`. */
449
+ type TvRemoteCommandResult = {
450
+ action: 'tv-remote';
451
+ button: TvRemoteButton;
452
+ durationMs?: number;
453
+ message: string;
454
+ };
355
455
  //#endregion
356
456
  //#region src/contracts/clipboard.d.ts
357
457
  /**
@@ -387,8 +487,10 @@ type AppStateCommandResult = {
387
487
  appName: string;
388
488
  appBundleId?: string;
389
489
  source: 'session';
390
- surface: SessionSurface; /** iOS only — the session device's UDID. */
391
- device_udid?: string; /** iOS only — the simulator set path, or `null` when unknown. */
490
+ surface: SessionSurface;
491
+ /** iOS only — the session device's UDID. */
492
+ device_udid?: string;
493
+ /** iOS only — the simulator set path, or `null` when unknown. */
392
494
  ios_simulator_device_set?: string | null;
393
495
  } | {
394
496
  platform: 'android';
@@ -427,6 +529,86 @@ type KeyboardCommandResult = {
427
529
  message?: string;
428
530
  };
429
531
  //#endregion
532
+ //#region src/contracts/wait.d.ts
533
+ /**
534
+ * Public daemon result for `wait`. The runtime-local result carries a `kind`
535
+ * discriminant, but `toDaemonWaitData` intentionally projects the normal daemon
536
+ * payload to this compact shape. The direct iOS selector fast path may still
537
+ * include `kind: 'selector'` additively.
538
+ */
539
+ type WaitCommandResult = {
540
+ waitedMs: number;
541
+ kind?: 'selector';
542
+ text?: string;
543
+ selector?: string;
544
+ captures?: number;
545
+ nodeCount?: number;
546
+ hint?: string;
547
+ warning?: string;
548
+ };
549
+ //#endregion
550
+ //#region src/contracts/prepare.d.ts
551
+ type PrepareIosRunnerCacheKind = 'exact' | 'restore-key' | 'miss' | 'external';
552
+ type PrepareIosRunnerArtifactState = 'valid' | 'rebuilt';
553
+ type PrepareIosRunnerTiming = {
554
+ totalMs: number;
555
+ additiveParts: {
556
+ buildMs?: number;
557
+ connectAfterBuildMs: number;
558
+ healthCheckMs: number;
559
+ };
560
+ containment: {
561
+ connectMs?: ['buildMs'];
562
+ healthCheckMs: [];
563
+ };
564
+ note: string;
565
+ };
566
+ /**
567
+ * Public daemon result for `prepare ios-runner`. The runner-local prepare result
568
+ * is projected by `prepareIosRunnerResponseData` with device identity and timing
569
+ * guidance before it reaches the client.
570
+ */
571
+ type PrepareCommandResult = {
572
+ action: 'ios-runner';
573
+ platform: PublicPlatform;
574
+ deviceId: string;
575
+ deviceName: string;
576
+ kind: DeviceKind;
577
+ durationMs: number;
578
+ runner: JsonObject;
579
+ cache?: PrepareIosRunnerCacheKind;
580
+ artifact?: PrepareIosRunnerArtifactState;
581
+ buildMs?: number;
582
+ connectMs: number;
583
+ healthCheckMs: number;
584
+ xctestrunPath?: string;
585
+ recoveryReason?: string;
586
+ failureReason?: string;
587
+ timing: PrepareIosRunnerTiming;
588
+ message: string;
589
+ };
590
+ //#endregion
591
+ //#region src/contracts/push.d.ts
592
+ type PushCommandResult = {
593
+ platform: 'ios';
594
+ bundleId: string;
595
+ message: string;
596
+ } | {
597
+ platform: 'android';
598
+ package: string;
599
+ action: string;
600
+ extrasCount: number;
601
+ message: string;
602
+ };
603
+ //#endregion
604
+ //#region src/contracts/app-events.d.ts
605
+ type TriggerAppEventCommandResult = {
606
+ event: string;
607
+ eventUrl: string;
608
+ transport: 'deep-link';
609
+ message: string;
610
+ };
611
+ //#endregion
430
612
  //#region src/core/command-descriptor/command-result.d.ts
431
613
  /**
432
614
  * The additive typed-result spine (ADR-0008, Phase 1 step 6).
@@ -443,7 +625,8 @@ type KeyboardCommandResult = {
443
625
  * interaction trio. Batch 3 adds `clipboard` (a closed `read`/`write` union) and
444
626
  * `appstate` (a closed `platform` union — Apple session state with the iOS-only
445
627
  * device locators, or Android package/activity). Batch 4 adds `keyboard` (a
446
- * closed flat shape). Each entry is grounded in a
628
+ * closed flat shape). Batch 5 adds the compact daemon projections for `wait`,
629
+ * `prepare`, `push`, and `trigger-app-event`. Each entry is grounded in a
447
630
  * re-read of the handler's literal return; see the per-type docstrings.
448
631
  */
449
632
  interface CommandResultMap {
@@ -460,6 +643,11 @@ interface CommandResultMap {
460
643
  clipboard: ClipboardCommandResult;
461
644
  appstate: AppStateCommandResult;
462
645
  keyboard: KeyboardCommandResult;
646
+ 'tv-remote': TvRemoteCommandResult;
647
+ wait: WaitCommandResult;
648
+ prepare: PrepareCommandResult;
649
+ push: PushCommandResult;
650
+ 'trigger-app-event': TriggerAppEventCommandResult;
463
651
  }
464
652
  /**
465
653
  * The typed result for a command named `N`. Seeded commands resolve to their
@@ -658,6 +846,7 @@ type AppOpenResult = {
658
846
  sessionStateDir?: string;
659
847
  runnerLogPath?: string;
660
848
  requestLogPath?: string;
849
+ eventLogPath?: string;
661
850
  appName?: string;
662
851
  appBundleId?: string;
663
852
  appId?: string;
@@ -787,6 +976,7 @@ type CaptureSnapshotResult = {
787
976
  type CaptureScreenshotOptions = AgentDeviceRequestOverrides & {
788
977
  path?: string;
789
978
  overlayRefs?: boolean;
979
+ pixelDensity?: number;
790
980
  fullscreen?: boolean;
791
981
  maxSize?: number;
792
982
  stabilize?: boolean;
@@ -862,6 +1052,10 @@ type ClipboardCommandOptions = (DeviceCommandBaseOptions & {
862
1052
  action: 'write';
863
1053
  text: string;
864
1054
  });
1055
+ type TvRemoteCommandOptions = DeviceCommandBaseOptions & {
1056
+ button: TvRemoteButton;
1057
+ durationMs?: number;
1058
+ };
865
1059
  type ReactNativeCommandOptions = DeviceCommandBaseOptions & {
866
1060
  action: 'dismiss-overlay';
867
1061
  };
@@ -878,7 +1072,7 @@ type ViewportCommandOptions = DeviceCommandBaseOptions & {
878
1072
  height: number;
879
1073
  };
880
1074
  type AgentDeviceCommandClient = {
881
- wait: (options: WaitCommandOptions) => Promise<CommandRequestResult>;
1075
+ wait: (options: WaitCommandOptions) => Promise<CommandResult<'wait'>>;
882
1076
  alert: (options?: AlertCommandOptions) => Promise<CommandRequestResult>;
883
1077
  appState: (options?: AppStateCommandOptions) => Promise<CommandResult<'appstate'>>;
884
1078
  back: (options?: BackCommandOptions) => Promise<CommandResult<'back'>>;
@@ -887,13 +1081,14 @@ type AgentDeviceCommandClient = {
887
1081
  appSwitcher: (options?: AppSwitcherCommandOptions) => Promise<CommandResult<'app-switcher'>>;
888
1082
  keyboard: (options?: KeyboardCommandOptions) => Promise<CommandResult<'keyboard'>>;
889
1083
  clipboard: (options: ClipboardCommandOptions) => Promise<CommandResult<'clipboard'>>;
1084
+ tvRemote: (options: TvRemoteCommandOptions) => Promise<CommandResult<'tv-remote'>>;
890
1085
  reactNative: (options: ReactNativeCommandOptions) => Promise<CommandRequestResult>;
891
1086
  doctor: (options?: DoctorCommandOptions) => Promise<CommandRequestResult>;
892
1087
  /**
893
1088
  * JSON prepare results include timing.additiveParts for additive wall-clock phases.
894
1089
  * Top-level buildMs/connectMs/healthCheckMs are diagnostics and may overlap.
895
1090
  */
896
- prepare: (options: PrepareCommandOptions) => Promise<CommandRequestResult>;
1091
+ prepare: (options: PrepareCommandOptions) => Promise<CommandResult<'prepare'>>;
897
1092
  viewport: (options: ViewportCommandOptions) => Promise<CommandResult<'viewport'>>;
898
1093
  };
899
1094
  type SelectorSnapshotCommandOptions = Pick<CaptureSnapshotOptions, 'depth' | 'scope' | 'raw'>;
@@ -934,11 +1129,11 @@ type DeviceBootOptions = DeviceCommandBaseOptions & {
934
1129
  type DeviceShutdownOptions = DeviceCommandBaseOptions;
935
1130
  type AppPushOptions = DeviceCommandBaseOptions & {
936
1131
  app: string;
937
- payload: string | Record<string, unknown>;
1132
+ payload: string | JsonObject;
938
1133
  };
939
1134
  type AppTriggerEventOptions = DeviceCommandBaseOptions & {
940
1135
  event: string;
941
- payload?: Record<string, unknown>;
1136
+ payload?: JsonObject;
942
1137
  };
943
1138
  type CaptureDiffOptions = DeviceCommandBaseOptions & Pick<CaptureSnapshotOptions, 'interactiveOnly' | 'depth' | 'scope' | 'raw'> & {
944
1139
  kind: 'snapshot';
@@ -1044,7 +1239,7 @@ type IsTextPredicateOptions = DeviceCommandBaseOptions & SelectorSnapshotCommand
1044
1239
  value: string;
1045
1240
  };
1046
1241
  type IsStatePredicateOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & {
1047
- predicate: 'visible' | 'hidden' | 'exists' | 'editable' | 'selected';
1242
+ predicate: 'visible' | 'hidden' | 'exists' | 'editable' | 'selected' | 'focused';
1048
1243
  selector: string;
1049
1244
  value?: never;
1050
1245
  };
@@ -1066,7 +1261,8 @@ type FindOptions = (FindBaseOptions & {
1066
1261
  });
1067
1262
  type ReplayRunOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & {
1068
1263
  path: string;
1069
- update?: boolean; /** @deprecated Use backend: 'maestro'. */
1264
+ update?: boolean;
1265
+ /** @deprecated Use backend: 'maestro'. */
1070
1266
  maestro?: boolean;
1071
1267
  backend?: string;
1072
1268
  env?: string[];
@@ -1074,7 +1270,8 @@ type ReplayRunOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOption
1074
1270
  };
1075
1271
  type ReplayTestOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & {
1076
1272
  paths: string[];
1077
- update?: boolean; /** @deprecated Use backend: 'maestro'. */
1273
+ update?: boolean;
1274
+ /** @deprecated Use backend: 'maestro'. */
1078
1275
  maestro?: boolean;
1079
1276
  backend?: string;
1080
1277
  env?: string[];
@@ -1082,7 +1279,8 @@ type ReplayTestOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptio
1082
1279
  timeoutMs?: number;
1083
1280
  retries?: number;
1084
1281
  recordVideo?: boolean;
1085
- artifactsDir?: string; /** @deprecated Use the CLI --reporter junit:<path> or --report-junit <path>. */
1282
+ artifactsDir?: string;
1283
+ /** @deprecated Use the CLI --reporter junit:<path> or --report-junit <path>. */
1086
1284
  reportJunit?: string;
1087
1285
  shardAll?: number;
1088
1286
  shardSplit?: number;
@@ -1112,6 +1310,10 @@ type LogsOptions = AgentDeviceRequestOverrides & {
1112
1310
  message?: string;
1113
1311
  restart?: boolean;
1114
1312
  };
1313
+ type EventsOptions = AgentDeviceRequestOverrides & {
1314
+ cursor?: string;
1315
+ limit?: number;
1316
+ };
1115
1317
  type NetworkOptions = AgentDeviceRequestOverrides & {
1116
1318
  action?: 'dump' | 'log';
1117
1319
  limit?: number;
@@ -1130,6 +1332,7 @@ type RecordOptions = AgentDeviceRequestOverrides & {
1130
1332
  maxSize?: number;
1131
1333
  quality?: RecordingExportQuality;
1132
1334
  hideTouches?: boolean;
1335
+ recordingScope?: RecordingScope;
1133
1336
  };
1134
1337
  type TraceOptions = AgentDeviceRequestOverrides & {
1135
1338
  action: 'start' | 'stop';
@@ -1190,8 +1393,8 @@ type AgentDeviceClient = {
1190
1393
  list: (options?: AppListOptions) => Promise<string[]>;
1191
1394
  open: (options: AppOpenOptions) => Promise<AppOpenResult>;
1192
1395
  close: (options?: AppCloseOptions) => Promise<AppCloseResult>;
1193
- push: (options: AppPushOptions) => Promise<CommandRequestResult>;
1194
- triggerEvent: (options: AppTriggerEventOptions) => Promise<CommandRequestResult>;
1396
+ push: (options: AppPushOptions) => Promise<CommandResult<'push'>>;
1397
+ triggerEvent: (options: AppTriggerEventOptions) => Promise<CommandResult<'trigger-app-event'>>;
1195
1398
  };
1196
1399
  materializations: {
1197
1400
  release: (options: MaterializationReleaseOptions) => Promise<MaterializationReleaseResult>;
@@ -1242,6 +1445,7 @@ type AgentDeviceClient = {
1242
1445
  observability: {
1243
1446
  perf: (options?: PerfOptions) => Promise<CommandRequestResult>;
1244
1447
  logs: (options?: LogsOptions) => Promise<CommandRequestResult>;
1448
+ events: (options?: EventsOptions) => Promise<CommandRequestResult>;
1245
1449
  network: (options?: NetworkOptions) => Promise<CommandRequestResult>;
1246
1450
  audio: (options?: AudioOptions) => Promise<CommandRequestResult>;
1247
1451
  };
@@ -1,3 +1,3 @@
1
- import{t as e}from"./rolldown-runtime.js";import{F as t}from"./sdk-contracts.js";import{j as n,u as r}from"./sdk-android-adb.js";import{t as i}from"./timeouts.js";import{tt as a}from"./device-rotation.js";import{s as o}from"./logcat.js";import{l as s,r as c}from"./device-input-state.js";import{p as l}from"./snapshot-helper.js";import{Ct as u}from"./internal/daemon.js";function ee(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=ne(t),r={failureReason:t.reason??`text_mismatch`,targetInput:p(t.targetInput),actualInput:p(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function d(e){return e?e.password?!0:f(e.text):!1}function f(e){return e?Array.from(e).every(te):!1}function p(e){if(!e)return null;let t=d(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function te(e){return e===`•`||e===`*`||e===`●`}function ne(e){return e.masked===!0||d(e.targetInput)||d(e.actualInput)}async function m(e,t,n,r){let a=[0,150,350],o=null,s=null,c=await D(e);for(let l of a){l>0&&await i(l);let a=await v(e,t,n,r,c);if(o=a,a.reason===`ime_capture`)return a;s=a.ok?a:null}return s??o??{ok:!1,actual:null,reason:`text_mismatch`,targetInput:null,actualInput:null}}async function re(e,t,n){return h(await u(e),t,n)}function ie(e,t,n,r,i={}){let a=y(e,t,n,i);return b(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:x(a,r)??S(a,r)}function h(e,t,n){return y(e,t,n).actualInput?.text??null}function g(e){return e?.reason===`ime_capture`?`Android fill input was captured by the active keyboard instead of the app field`:e?.reason===`masked_unverified`?`Android fill verification could not confirm masked text value`:`Android fill verification failed`}function _(e,t){let n=ee(e,t);return t?.reason===`ime_capture`&&(n.hint=`The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill.`),n}async function v(e,t,n,r,i){return ie(await u(e),t,n,r,i)}function y(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of l(e)){let e=E(a,r);e&&O(i,e,t,n)}return oe(i)}function b(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function x(e,t){let n=e.actualInput;if(!n||!A(n))return null;let r=n.text??null,i=Array.from(r??``).length,a=Array.from(t).length,o=r!==null&&i>0&&a>0&&i===a;return{ok:o,actual:r,reason:o?void 0:`masked_unverified`,masked:!0,targetInput:e.targetInput,actualInput:n}}function S(e,t){let n=e.actualInput?.text??null;return{ok:C(n,t),actual:n,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:e.actualInput}}function C(e,t){if(e===t)return!0;let n=w(e),r=w(t);return!n||!r?!1:!!(n===r||T(n,r))}function w(e){return(e??``).replace(/\s+/g,` `).trim()}function T(e,t){if(e.length!==t.length||e.length===0||e.slice(1)!==t.slice(1))return!1;let n=e[0],r=t[0];return!n||!r?!1:r.toLowerCase()===r&&n===r.toUpperCase()}function E(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:s({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:se(e.className??``)}}async function D(e){try{return{activeInputMethodPackage:(await c(e)).inputMethodPackage}}catch(e){return n({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function O(e,t,n,r){let i=ae(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=k(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=k(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=k(e.anyAtPoint,t))}function ae(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function k(e,t){return e&&e.area<t.area?e:t}function oe(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function se(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function A(e){return d(e)}var j=e({appSwitcherAndroid:()=>R,backAndroid:()=>P,fillAndroid:()=>H,focusAndroid:()=>V,getAndroidScreenSize:()=>q,homeAndroid:()=>F,longPressAndroid:()=>z,pressAndroid:()=>M,pressAndroidEnter:()=>I,readAndroidTextAtPoint:()=>re,rotateAndroid:()=>L,scrollAndroid:()=>W,swipeAndroid:()=>N,typeAndroid:()=>B});async function M(e,t,n){await o(e,[`shell`,`input`,`tap`,String(t),String(n)])}async function N(e,t,n,r,i,a=250){await o(e,[`shell`,`input`,`swipe`,String(t),String(n),String(r),String(i),String(a)])}async function P(e){await o(e,[`shell`,`input`,`keyevent`,`4`])}async function F(e){await o(e,[`shell`,`input`,`keyevent`,`3`])}async function I(e){await o(e,[`shell`,`input`,`keyevent`,`ENTER`])}async function L(e,t){let n=G(t);await o(e,[`shell`,`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await o(e,[`shell`,`settings`,`put`,`system`,`user_rotation`,n])}async function R(e){await o(e,[`shell`,`input`,`keyevent`,`187`])}async function z(e,t,n,r=800){await o(e,[`shell`,`input`,`swipe`,String(t),String(n),String(t),String(n),String(r)])}async function B(e,t,n=0){let i=r(e);if(i){await i({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}if(X(t),await K(e,`type`),n>0&&Array.from(t).length>1){await Y(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Y(e,{action:`type`,text:t,chunkSize:J,delayMs:0})}async function V(e,t,n){await M(e,t,n)}async function H(e,t,n,i,a=0){let o=r(e);if(o){await o({action:`fill`,target:{x:t,y:n},text:i,delayMs:a}),$(`fill`,`provider-native`,i);let r=await m(e,t,n,i);if(r.ok)return;U(i,r)}X(i);let s=Array.from(i).length,c=[{clearPadding:12,minClear:8,maxClear:48,chunkSize:a>0?1:J,inputDelayMs:a},{clearPadding:24,minClear:16,maxClear:96,chunkSize:a>0?1:4,inputDelayMs:a>0?a:15}],l=null;for(let r of c){await V(e,t,n),await K(e,`fill`),await fe(e,pe(s+r.clearPadding,r.minClear,r.maxClear)),await Y(e,{action:`fill`,text:i,chunkSize:r.chunkSize,delayMs:r.inputDelayMs});let a=await m(e,t,n,i);if(l=a,a.ok)return;a.reason===`ime_capture`&&U(i,a)}U(i,l)}function U(e,n){throw new t(`COMMAND_FAILED`,g(n),_(e,n))}async function W(e,t,n){let r=await q(e),i=a({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:r.width,referenceHeight:r.height}),s=n?.durationMs??300;return await o(e,[`shell`,`input`,`swipe`,String(i.x1),String(i.y1),String(i.x2),String(i.y2),String(s)]),{...i,...n?.durationMs===void 0?{}:{durationMs:n.durationMs}}}function G(e){switch(e){case`portrait`:return`0`;case`landscape-left`:return`1`;case`portrait-upside-down`:return`2`;case`landscape-right`:return`3`;default:throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`)}}async function K(e,r){let i;try{i=await c(e)}catch(e){n({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:r,error:e instanceof Error?e.message:String(e)}});return}if(i.inputOwner===`ime`)throw new t(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:r,inputOwner:i.inputOwner,inputType:i.inputType,type:i.type,inputMethodPackage:i.inputMethodPackage,focusedPackage:i.focusedPackage,focusedResourceId:i.focusedResourceId,nextAction:`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`})}async function q(e){let n=(await o(e,[`shell`,`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new t(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(n[1]),height:Number(n[2])}}const J=8;async function Y(e,t){let n=t.text.split(`
2
- `);for(let[r,a]of n.entries()){let s=de(a,t.chunkSize);for(let[a,o]of s.entries())await ce(e,o),t.delayMs>0&&(a+1<s.length||r+1<n.length)&&await i(t.delayMs);r+1<n.length&&await o(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(t.action,`adb-shell`,t.text)}async function ce(e,t){if(t)try{await o(e,[`shell`,`input`,`text`,Z(t)])}catch(e){throw ue(e)?Q(t,e):e}}function X(e){if(!le(e))throw Q(e)}function le(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
3
- `&&(e<32||e>126))return!1}return!0}function Z(e){return e.replace(/ /g,`%s`)}function ue(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details?.stderr,r=(typeof n==`string`?n:``).toLowerCase();return!!(r.includes(`exception occurred while executing 'text'`)||r.includes(`nullpointerexception`)&&r.includes(`inputshellcommand.sendtext`))}function Q(e,n){return new t(`COMMAND_FAILED`,`Android text input requires provider-native text injection for non-ASCII/control characters; the current adb-shell fallback supports ASCII text only.`,{backend:`adb-shell`,textLength:Array.from(e).length,textPreview:e.slice(0,32)},n instanceof Error?n:void 0)}function de(e,t){let n=Math.max(1,Math.floor(t)),r=[],i=Array.from(e);for(let e=0;e<i.length;e+=n)r.push(i.slice(e,e+n).join(``));return r.length>0?r:[``]}function $(e,t,r){n({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(r).length}})}async function fe(e,t){let n=Math.max(0,t);await o(e,[`shell`,`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await o(e,[`shell`,`input`,`keyevent`,...Array(r).fill(`KEYCODE_DEL`)],{allowFailure:!0})}}function pe(e,t,n){return Math.max(t,Math.min(n,e))}export{q as a,z as c,W as d,N as f,V as i,M as l,P as n,F as o,B as p,H as r,j as s,R as t,L as u};
1
+ import{t as e}from"./rolldown-runtime.js";import{F as t}from"./sdk-contracts.js";import{j as n,u as r}from"./sdk-android-adb.js";import{i,st as a}from"./tv-remote.js";import{t as o}from"./timeouts.js";import{p as s,r as c}from"./android-input-ownership.js";import{r as l}from"./device-input-state.js";import{p as u}from"./snapshot-helper.js";import{Et as d}from"./internal/daemon.js";function ee(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=h(t),r={failureReason:t.reason??`text_mismatch`,targetInput:m(t.targetInput),actualInput:m(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function f(e){return e?e.password?!0:p(e.text):!1}function p(e){return e?Array.from(e).every(te):!1}function m(e){if(!e)return null;let t=f(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function te(e){return e===`•`||e===`*`||e===`●`}function h(e){return e.masked===!0||f(e.targetInput)||f(e.actualInput)}async function g(e,t,n,r){let i=[0,150,350],a=null,s=null,c=await ae(e);for(let l of i){l>0&&await o(l);let i=await S(e,t,n,r,c);if(a=i,i.reason===`ime_capture`)return i;s=i.ok?i:null}return s??a??{ok:!1,actual:null,reason:`text_mismatch`,targetInput:null,actualInput:null}}async function _(e,t,n){return y(await d(e),t,n)}function v(e,t,n,r,i={}){let a=C(e,t,n,i);return w(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:T(a,r)??E(a,r)}function y(e,t,n){return C(e,t,n).actualInput?.text??null}function b(e){return e?.reason===`ime_capture`?`Android fill input was captured by the active keyboard instead of the app field`:e?.reason===`masked_unverified`?`Android fill verification could not confirm masked text value`:`Android fill verification failed`}function x(e,t){let n=ee(e,t);return t?.reason===`ime_capture`&&(n.hint=`The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill.`),n}async function S(e,t,n,r,i){return v(await d(e),t,n,r,i)}function C(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of u(e)){let e=ie(a,r);e&&oe(i,e,t,n)}return ce(i)}function w(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function T(e,t){let n=e.actualInput;if(!n||!A(n))return null;let r=n.text??null,i=Array.from(r??``).length,a=Array.from(t).length,o=r!==null&&i>0&&a>0&&i===a;return{ok:o,actual:r,reason:o?void 0:`masked_unverified`,masked:!0,targetInput:e.targetInput,actualInput:n}}function E(e,t){let n=e.actualInput?.text??null;return{ok:ne(n,t),actual:n,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:e.actualInput}}function ne(e,t){if(e===t)return!0;let n=D(e),r=D(t);return!n||!r?!1:!!(n===r||re(n,r))}function D(e){return(e??``).replace(/\s+/g,` `).trim()}function re(e,t){if(e.length!==t.length||e.length===0||e.slice(1)!==t.slice(1))return!1;let n=e[0],r=t[0];return!n||!r?!1:r.toLowerCase()===r&&n===r.toUpperCase()}function ie(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:c({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:k(e.className??``)}}async function ae(e){try{return{activeInputMethodPackage:(await l(e)).inputMethodPackage}}catch(e){return n({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function oe(e,t,n,r){let i=se(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=O(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=O(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=O(e.anyAtPoint,t))}function se(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function O(e,t){return e&&e.area<t.area?e:t}function ce(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function k(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function A(e){return f(e)}var j=e({appSwitcherAndroid:()=>z,backAndroid:()=>F,fillAndroid:()=>U,focusAndroid:()=>H,getAndroidScreenSize:()=>q,homeAndroid:()=>I,longPressAndroid:()=>B,pressAndroid:()=>M,pressAndroidEnter:()=>L,pressAndroidTvRemote:()=>N,readAndroidTextAtPoint:()=>_,rotateAndroid:()=>R,scrollAndroid:()=>G,swipeAndroid:()=>P,typeAndroid:()=>V});async function M(e,t,n){await s(e,[`shell`,`input`,`tap`,String(t),String(n)])}async function N(e,t,n){let r=i(t);await s(e,[`shell`,`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function P(e,t,n,r,i,a=250){await s(e,[`shell`,`input`,`swipe`,String(t),String(n),String(r),String(i),String(a)])}async function F(e){await s(e,[`shell`,`input`,`keyevent`,`4`])}async function I(e){await s(e,[`shell`,`input`,`keyevent`,`3`])}async function L(e){await s(e,[`shell`,`input`,`keyevent`,`ENTER`])}async function R(e,t){let n=le(t);await s(e,[`shell`,`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await s(e,[`shell`,`settings`,`put`,`system`,`user_rotation`,n])}async function z(e){await s(e,[`shell`,`input`,`keyevent`,`187`])}async function B(e,t,n,r=800){await s(e,[`shell`,`input`,`swipe`,String(t),String(n),String(t),String(n),String(r)])}async function V(e,t,n=0){let i=r(e);if(i){await i({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}if(X(t),await K(e,`type`),n>0&&Array.from(t).length>1){await Y(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Y(e,{action:`type`,text:t,chunkSize:J,delayMs:0})}async function H(e,t,n){await M(e,t,n)}async function U(e,t,n,i,a=0){let o=r(e);if(o){await o({action:`fill`,target:{x:t,y:n},text:i,delayMs:a}),$(`fill`,`provider-native`,i);let r=await g(e,t,n,i);if(r.ok)return;W(i,r)}X(i);let s=Array.from(i).length,c=[{clearPadding:12,minClear:8,maxClear:48,chunkSize:a>0?1:J,inputDelayMs:a},{clearPadding:24,minClear:16,maxClear:96,chunkSize:a>0?1:4,inputDelayMs:a>0?a:15}],l=null;for(let r of c){await H(e,t,n),await K(e,`fill`),await me(e,he(s+r.clearPadding,r.minClear,r.maxClear)),await Y(e,{action:`fill`,text:i,chunkSize:r.chunkSize,delayMs:r.inputDelayMs});let a=await g(e,t,n,i);if(l=a,a.ok)return;a.reason===`ime_capture`&&W(i,a)}W(i,l)}function W(e,n){throw new t(`COMMAND_FAILED`,b(n),x(e,n))}async function G(e,t,n){let r=await q(e),i=a({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:r.width,referenceHeight:r.height}),o=n?.durationMs??300;return await s(e,[`shell`,`input`,`swipe`,String(i.x1),String(i.y1),String(i.x2),String(i.y2),String(o)]),{...i,...n?.durationMs===void 0?{}:{durationMs:n.durationMs}}}function le(e){switch(e){case`portrait`:return`0`;case`landscape-left`:return`1`;case`portrait-upside-down`:return`2`;case`landscape-right`:return`3`;default:throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`)}}async function K(e,r){let i;try{i=await l(e)}catch(e){n({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:r,error:e instanceof Error?e.message:String(e)}});return}if(i.inputOwner===`ime`)throw new t(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:r,inputOwner:i.inputOwner,inputType:i.inputType,type:i.type,inputMethodPackage:i.inputMethodPackage,focusedPackage:i.focusedPackage,focusedResourceId:i.focusedResourceId,nextAction:`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`})}async function q(e){let n=(await s(e,[`shell`,`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new t(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(n[1]),height:Number(n[2])}}const J=8;async function Y(e,t){let n=t.text.split(`
2
+ `);for(let[r,i]of n.entries()){let a=pe(i,t.chunkSize);for(let[i,s]of a.entries())await ue(e,s),t.delayMs>0&&(i+1<a.length||r+1<n.length)&&await o(t.delayMs);r+1<n.length&&await s(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(t.action,`adb-shell`,t.text)}async function ue(e,t){if(t)try{await s(e,[`shell`,`input`,`text`,Z(t)])}catch(e){throw fe(e)?Q(t,e):e}}function X(e){if(!de(e))throw Q(e)}function de(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
3
+ `&&(e<32||e>126))return!1}return!0}function Z(e){return e.replace(/ /g,`%s`)}function fe(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details?.stderr,r=(typeof n==`string`?n:``).toLowerCase();return!!(r.includes(`exception occurred while executing 'text'`)||r.includes(`nullpointerexception`)&&r.includes(`inputshellcommand.sendtext`))}function Q(e,n){return new t(`COMMAND_FAILED`,`Android text input requires provider-native text injection for non-ASCII/control characters; the current adb-shell fallback supports ASCII text only.`,{backend:`adb-shell`,textLength:Array.from(e).length,textPreview:e.slice(0,32)},n instanceof Error?n:void 0)}function pe(e,t){let n=Math.max(1,Math.floor(t)),r=[],i=Array.from(e);for(let e=0;e<i.length;e+=n)r.push(i.slice(e,e+n).join(``));return r.length>0?r:[``]}function $(e,t,r){n({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(r).length}})}async function me(e,t){let n=Math.max(0,t);await s(e,[`shell`,`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await s(e,[`shell`,`input`,`keyevent`,...Array(r).fill(`KEYCODE_DEL`)],{allowFailure:!0})}}function he(e,t,n){return Math.max(t,Math.min(n,e))}export{q as a,B as c,R as d,G as f,H as i,M as l,V as m,F as n,I as o,P as p,U as r,j as s,z as t,N as u};
@@ -1 +1 @@
1
- import{j as e}from"./sdk-android-adb.js";import{t}from"./snapshot-quality.js";import{Bt as n,Ft as r,Nt as i,Pt as a,Vt as o,jt as s,kt as c,vt as l,yt as u}from"./internal/daemon.js";import{a as d}from"./input-actions.js";function f(e){let{session:t,sessionStore:s,command:c,positionals:u,retryPositionals:d,flags:f,result:p,responseData:m,actionStartedAt:h,actionFinishedAt:g,androidFreshnessBaseline:_}=e,v=r(f);return s.recordAction(t,{command:c,positionals:u,flags:v??{},result:p}),a({session:t,command:c,positionals:d??u,flags:f,preSnapshot:t.snapshot}),n(c)&&o(t,c,_??t.snapshot),i(t,c,d??u,f),l(t,c,u,p,v??{},h,g),{ok:!0,data:m}}async function p(e){let{session:t,flags:n,sessionStore:r,contextFromFlags:i,captureSnapshotForSession:a}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if(t.device.platform===`android`){let e=await d(t.device),n={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=n),n}let o=u(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=u(await a(t,n,r,i,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function m(t){try{return await p(t)}catch(n){e({level:`warn`,phase:`touch_reference_frame_resolve_failed`,data:{platform:t.session.device.platform,error:n instanceof Error?n.message:String(n)}});return}}function h(e){return u({nodes:e,createdAt:0})}async function g(e,n,r,i,a){let o={...n??{},snapshotInteractiveOnly:a.interactiveOnly},l=i(o,e.appBundleId,e.trace?.outPath),{snapshot:u}=await s({device:e.device,session:e,flags:o,outPath:o.out,logPath:l.logPath??``,includeRects:a.includeRects,androidFreshnessMode:a.androidFreshnessMode});return t(u.snapshotQuality)||(c(e,u),r.set(e.name,e)),u}export{f as i,h as n,m as r,g as t};
1
+ import{j as e}from"./sdk-android-adb.js";import{t}from"./snapshot-quality.js";import{It as n,Lt as r,Mt as i,Pt as a,Rt as o,St as s,Ut as c,Wt as l,xt as u}from"./internal/daemon.js";import{a as d}from"./input-actions.js";function f(e){let{session:t,sessionStore:i,command:a,positionals:s,retryPositionals:d,flags:f,result:p,responseData:m,actionStartedAt:h,actionFinishedAt:g,androidFreshnessBaseline:_}=e,v=o(f);return i.recordAction(t,{command:a,positionals:s,flags:v??{},result:p}),r({session:t,command:a,positionals:d??s,flags:f,preSnapshot:t.snapshot}),c(a)&&l(t,a,_??t.snapshot),n(t,a,d??s,f),u(t,a,s,p,v??{},h,g),{ok:!0,data:m}}async function p(e){let{session:t,flags:n,sessionStore:r,contextFromFlags:i,captureSnapshotForSession:a}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if(t.device.platform===`android`){let e=await d(t.device),n={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=n),n}let o=s(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let c=s(await a(t,n,r,i,{interactiveOnly:!0}));return c&&t.recording&&(t.recording.touchReferenceFrame=c),c}async function m(t){try{return await p(t)}catch(n){e({level:`warn`,phase:`touch_reference_frame_resolve_failed`,data:{platform:t.session.device.platform,error:n instanceof Error?n.message:String(n)}});return}}function h(e){return s({nodes:e,createdAt:0})}async function g(e,n,r,o,s){let c={...n??{},snapshotInteractiveOnly:s.interactiveOnly},l=o(c,e.appBundleId,e.trace?.outPath),{snapshot:u}=await a({device:e.device,session:e,flags:c,outPath:c.out,logPath:l.logPath??``,includeRects:s.includeRects,androidFreshnessMode:s.androidFreshnessMode});return t(u.snapshotQuality)||(i(e,u),r.set(e.name,e)),u}export{f as i,h as n,m as r,g as t};
@@ -1 +1 @@
1
- import{B as e,F as t,I as n,b as r,m as i}from"./sdk-contracts.js";import{j as a}from"./sdk-android-adb.js";import{d as o,u as s,w as c}from"./sdk-batch.js";import{_t as l,gn as u,gt as d,ht as ee}from"./device-rotation.js";import{t as f}from"./runtime.js";import{Et as p,Ht as m,Ot as h,Qt as g,St as _,Tt as v,Wt as y,Xt as b,Yt as x,Zt as S,kt as C,xt as w,zt as te}from"./internal/daemon.js";import{n as ne}from"./provider.js";import{_ as T,c as re,d as ie,f as ae,g as E,h as oe,l as se,m as D,n as O,o as k,p as A,r as ce,s as le,u as ue,v as de,y as j}from"./selector-runtime.js";import{i as M,n as N,r as fe,t as P}from"./interaction-snapshot.js";function F(e){let{source:t,referenceFrame:n,extra:r}=e;if(t.kind===`runner-payload`){let e={targetKind:t.targetKind,...r??{}};return{result:R({data:t.data,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:n,extra:e}),responseData:R({data:B(t.data),fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:n,extra:e})}}let{result:i}=t,a=ae(i),o={targetKind:i.kind,...a,...I(i.settle,e.settleRefsGeneration),...r??{}},s=R({data:i.backendResult,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:o}),c=R({data:B(i.backendResult),fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:o}),l=L(`warning`in i?i.warning:void 0,e.staleRefsWarning);return l&&(s.warning=l,c.warning=l),{result:s,responseData:c}}function I(e,t){return!e?.diff||t===void 0?{}:{settle:{...e,refsGeneration:t}}}function L(e,t){return t?e?`${e} ${t}`:t:e}function R(e){let{data:t,fallbackX:n,fallbackY:r,referenceFrame:i,extra:a}=e,o=pe(a,n,r)??(typeof t?.message==`string`?t.message:void 0);return z({...t??{},...n===void 0||r===void 0?{}:{x:n,y:r},...i??{},...a??{},...u(o)})}function z(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function B(e){if(!e)return;let t=Object.fromEntries(Object.entries(e).filter(([e,t])=>V(e,t)));return Object.keys(t).length>0?t:void 0}function V(e,t){switch(e){case`gestureStartUptimeMs`:case`gestureEndUptimeMs`:case`sequenceResults`:return!1;case`count`:return t!==1;case`intervalMs`:case`holdMs`:case`jitterPx`:return t!==0;case`doubleTap`:return t!==!1;default:return!0}}function pe(e,t,n){let r=H(e,`text`);if(r!==void 0)return`Filled ${Array.from(r).length} chars`;let i=me(t,n),a=he(e);if(a)return _e(a,e??{},i);if(i)return ge(e,i)}function H(e,t){let n=e?.[t];return typeof n==`string`?n:void 0}function me(e,t){return e===void 0||t===void 0?``:` (${e}, ${t})`}function he(e){let t=H(e,`ref`);return t===void 0?H(e,`selector`):`@${t}`}function ge(e,t){return e?.gesture===`longpress`?`Long pressed${t}`:`Tapped${t}`}function _e(e,t,n){let r=typeof t.button==`string`?t.button:void 0;return t.gesture===`longpress`?`Long pressed ${e}${n}`:r&&r!==`primary`?`Clicked ${r} ${e}${n}`:`Tapped ${e}${n}`}function U(e,t){return!i(e.device)||e.surface!==`desktop`&&e.surface!==`menubar`||e.surface===`menubar`&&(t===`click`||t===`press`)?null:b(`UNSUPPORTED_OPERATION`,`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}function W(e){let n=e.sessionStore.get(e.sessionName);if(!n)throw new t(`SESSION_NOT_FOUND`,x);return f({backend:ve({...e,session:n}),...k(`interaction commands`,{plural:!0}),sessions:v({sessionName:e.sessionName,getSession:()=>n,recordOptions:{includeSnapshot:!0},setRecord:t=>{t.snapshot&&(C(n,t.snapshot),e.sessionStore.set(e.sessionName,n))}})})}function ve(e){let{req:t,session:n}=e,i=ye(n);return{platform:r(n.device),captureSnapshot:async(r,i)=>({snapshot:await e.captureSnapshotForSession(n,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:i?.interactiveOnly===!0,includeRects:i?.includeRects===!0})}),tap:async(r,i)=>G(await m(n.device,`press`,[String(i.x),String(i.y)],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath))),tapTarget:i?.clickRef?async(e,t)=>(await i.clickRef?.(t.ref),{ref:E(t.ref)}):void 0,fill:async(r,i,a)=>G(await m(n.device,`fill`,[String(i.x),String(i.y),a],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath))),fillTarget:i?.fillRef?async(e,t,n,r)=>(await i.fillRef?.(t.ref,n,r),{ref:E(t.ref),text:n,delayMs:r?.delayMs??0}):void 0,longPress:async(r,i,a)=>G(await m(n.device,`longpress`,[String(i.x),String(i.y),...a?.durationMs===void 0?[]:[String(a.durationMs)]],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath))),typeText:async(r,i)=>G(await m(n.device,`type`,[i],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath)))}}function ye(e){if(e.device.platform!==`web`)return;let t=ne();return t.clickRef||t.fillRef?t:void 0}function G(e){return e&&typeof e==`object`?e:void 0}async function be(e){switch(e.req.command){case`press`:return await K(e,`press`);case`click`:return await K(e,`click`);case`longpress`:return await K(e,`longpress`);case`fill`:return await ke(e);default:return null}}async function K(e,t){let{req:n,sessionName:i,sessionStore:a}=e,o=a.get(i);if(!o)return S();let s=t===`click`?`click`:t,c=t===`longpress`?`longpress`:`press`,u=U(o,s);if(u)return u;let f=g(c,o.device);if(f)return f;let p=j(t,n.flags);if(p)return p;let m=l(n.flags),_=ee(m);if(t!==`longpress`&&m!==`primary`){let e=d({commandLabel:s,platform:r(o.device),button:m,count:n.flags?.count,intervalMs:n.flags?.intervalMs,holdMs:n.flags?.holdMs,jitterPx:n.flags?.jitterPx,doubleTap:n.flags?.doubleTap});if(e)return b(e.code,e.message,e.details)}let v=t===`longpress`?D(n.positionals??[]):oe(n.positionals??[],s);if(!v.ok)return v.response;let y=v.target.kind===`ref`?h({session:o,ref:v.target.ref,mintedGeneration:v.refGeneration}):void 0,x;if(v.target.kind===`ref`){let r=e.refSnapshotFlagGuardResponse(t===`longpress`?`longpress`:`press`,n.flags);if(r)return r;x=await Q(e,o)}let C=Ce({session:o,commandLabel:s,target:v.target,flags:n.flags});if(C){let t=await Te(e,o,C);if(t)return t}let w=t===`longpress`?v.durationMs:void 0;return await Z(e,{androidFreshnessBaseline:x,run:async e=>await q({runtime:e,command:t,target:v.target,sessionName:i,requestId:n.meta?.requestId,clickButton:m,flags:n.flags,durationMs:w}),afterRun:async e=>{o.lease?.leaseProvider||await se(o,ie(v.target,e))},buildPayloads:async n=>{let r=Se(n);return await xe({params:e,session:o,result:n,staleRefsWarning:y,extra:t===`longpress`?{...r===void 0?{}:{durationMs:r},gesture:`longpress`}:_})}})}async function q(e){let{runtime:t,command:n,target:r,sessionName:i,requestId:a,flags:o}=e,s=T(o);if(n===`longpress`)return await t.interactions.longPress(r,{session:i,requestId:a,durationMs:e.durationMs,settle:s});let c={session:i,requestId:a,button:e.clickButton,count:o?.count,intervalMs:o?.intervalMs,holdMs:o?.holdMs,jitterPx:o?.jitterPx,doubleTap:o?.doubleTap,verify:o?.verify,settle:s};return n===`click`?await t.interactions.click(r,c):await t.interactions.press(r,c)}async function xe(e){let{params:t,session:n,result:r,extra:i}=e,a=r.kind===`point`?await fe({session:n,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession}):N(n.snapshot?.nodes??[]);return F({source:{kind:`runtime`,result:r},referenceFrame:a,extra:i,staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:J(n,r)})}function J(e,t){if(t.settle?.diff)return p(e),e.snapshotGeneration}function Se(e){return`durationMs`in e?e.durationMs:void 0}function Ce(e){let{session:t,commandLabel:n,target:r,flags:i}=e;return n!==`click`||r.kind!==`selector`||we(i)||o(n)&&i?.verify===!0||s(n)&&i?.settle===!0?null:Y(t,r.selector,i)}function Y(e,t,n){let r=re({session:e,selectorExpression:t});return r?{...r,...n?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}function we(e){return e?.count!==void 0||e?.intervalMs!==void 0||e?.holdMs!==void 0||e?.jitterPx!==void 0||e?.doubleTap!==void 0||e?.clickButton!==void 0&&e.clickButton!==`primary`}async function Te(e,t,n){return await X({params:e,session:t,selector:n,command:`press`,positionals:[],extra:{selector:n.raw},fallbackPhase:`ios_direct_selector_tap_fallback`})}async function X(t){let{params:n,session:r,selector:i,command:o,positionals:s,extra:c,fallbackPhase:l}=t,u=Date.now();try{let e=await m(r.device,o,s,n.req.flags?.out,{...n.contextFromFlags(n.req.flags,r.appBundleId,r.trace?.outPath),directElementSelector:i,surface:r.surface})??{},t=Date.now(),a=De(e),{result:l,responseData:d}=F({source:{kind:`runner-payload`,targetKind:`selector`,data:e,point:a},referenceFrame:Oe(e),extra:{...c,...Ee(i,e)}});return M({session:r,sessionStore:n.sessionStore,command:n.req.command,positionals:n.req.positionals??[],retryPositionals:$(a),flags:n.req.flags,result:l,responseData:d,actionStartedAt:u,actionFinishedAt:t})}catch(t){return le(t,{delegateSemanticFailures:i.allowNonHittableCoordinateFallback!==!0})?(a({level:`debug`,phase:l,data:{selector:i.raw,error:t instanceof Error?t.message:String(t)}}),null):{ok:!1,error:e(t)}}}function Ee(e,t){if(!e.allowNonHittableCoordinateFallback)return{};let n=t.message===y;return{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:n,...n?{maestroFallbackReason:`non-hittable-coordinate`}:{}}}function De(e){let t=typeof e.x==`number`?e.x:void 0,n=typeof e.y==`number`?e.y:void 0;return t!==void 0&&n!==void 0?{x:t,y:n}:{x:0,y:0}}function Oe(e){return typeof e.referenceWidth==`number`&&typeof e.referenceHeight==`number`?{referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight}:void 0}async function ke(e){let{req:t,sessionName:n,sessionStore:r}=e,i=r.get(n);if(i){let e=U(i,`fill`);if(e)return e;let t=g(`fill`,i.device);if(t)return t}if(!i)return S();let a=j(`fill`,t.flags);if(a)return a;let o=A(t.positionals??[]);if(!o.ok)return o.response;let s=await Ae(e,i,o.target,o.refGeneration);if(s.response)return s.response;let{staleRefsWarning:c}=s;return await je(e,i,o.target,o.text)||await Z(e,{run:async e=>await e.interactions.fill(o.target,o.text,{session:n,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs,verify:t.flags?.verify,settle:T(t.flags)}),buildPayloads:e=>Me({session:i,result:e,text:o.text,staleRefsWarning:c})})}async function Ae(e,t,n,r){if(n.kind!==`ref`)return{};let i=h({session:t,ref:n.ref,mintedGeneration:r}),a=e.refSnapshotFlagGuardResponse(`fill`,e.req.flags);return a?{response:a,staleRefsWarning:i}:(await Q(e,t),{staleRefsWarning:i})}async function je(e,t,n,r){let i=Ne({session:t,target:n,flags:e.req.flags});return i?await Pe(e,t,i,r):null}function Me(e){let{session:t,result:n}=e,r=n.kind===`point`?void 0:N(t.snapshot?.nodes??[]);return F({source:{kind:`runtime`,result:n},referenceFrame:r,extra:{text:e.text},staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:J(t,n)})}function Ne(e){let{session:t,target:n,flags:r}=e;return n.kind!==`selector`||o(`fill`)&&r?.verify===!0||s(`fill`)&&r?.settle===!0?null:Y(t,n.selector,r)}async function Pe(e,t,n,r){return await X({params:e,session:t,selector:n,command:`fill`,positionals:[r],extra:{selector:n.raw,text:r},fallbackPhase:`ios_direct_selector_fill_fallback`})}async function Z(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return S();let i=W(e),a=Date.now();try{let{readiness:n,runtimeResult:o}=await Fe(r,e.req.command,async()=>{let e=await t.run(i);return await t.afterRun?.(e),e}),s=Date.now(),{result:c,responseData:l}=await t.buildPayloads(o);if(n.status===`recovered`){let e=typeof l.warning==`string`?`${l.warning} ${n.warning}`:n.warning;c.warning=e,l.warning=e}return M({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],retryPositionals:Le(e.req.command,o),flags:e.req.flags,result:c,responseData:l,actionStartedAt:a,actionFinishedAt:s,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(e){let t=n(e);if(ue(t))throw t;return Ie(e)}}async function Fe(e,t,n){if(e.lease?.leaseProvider)return{readiness:{status:`clear`},runtimeResult:await n()};let r=await w({session:e,command:t,phase:`before-command`}),i=await n();return await w({session:e,command:t,phase:`after-command`}),{readiness:r,runtimeResult:i}}async function Q(e,t){if(!te(t))return;let n=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(t,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:`ref-refresh`})}catch(t){a({level:`warn`,phase:`android_ref_snapshot_refresh_failed`,data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return n}function Ie(t){return{ok:!1,error:e(t)}}function Le(e,t){if(!(t.kind===`ref`&&!t.node)&&(e===`click`||e===`press`))return t.point?$(t.point):void 0}function $(e){return[String(e.x),String(e.y)]}async function Re(e){let t=await be({...e,captureSnapshotForSession:P,refSnapshotFlagGuardResponse:de});if(t)return t;switch(e.req.command){case c.type:return await ze({...e,captureSnapshotForSession:P});case`get`:return await O(e);case`is`:return await ce(e);default:return null}}async function ze(e){let{sessionName:t,sessionStore:n}=e,r=n.get(t);return r?g(c.type,r.device)||await Be(r)||await Ve(e,r):S()}async function Be(e){return e.device.platform===`android`&&e.recording&&(await _({session:e})).status===`failed`?b(`COMMAND_FAILED`,`Android system dialog blocked the recording session`):null}async function Ve(t,n){let{req:r,sessionName:i,sessionStore:a}=t,o=(r.positionals??[]).join(` `),s=W(t),c=Date.now();try{let e=await w({session:n,command:r.command,phase:`before-command`}),t=await s.interactions.typeText(o,{session:i,requestId:r.meta?.requestId,delayMs:r.flags?.delayMs});await w({session:n,command:r.command,phase:`after-command`});let l=Date.now(),d={...t.backendResult??{},text:t.text,delayMs:t.delayMs,...u(t.message??`Typed ${Array.from(t.text).length} chars`)};return e.status===`recovered`&&(d.warning=e.warning),M({session:n,sessionStore:a,command:r.command,positionals:r.positionals??[],flags:r.flags,result:d,responseData:d,actionStartedAt:c,actionFinishedAt:l})}catch(t){return{ok:!1,error:e(t)}}}export{Re as handleInteractionCommands};
1
+ import{B as e,F as t,I as n,b as r,f as i,m as a}from"./sdk-contracts.js";import{j as o}from"./sdk-android-adb.js";import{d as s,f as c,h as l,u}from"./sdk-batch.js";import{Ct as d,Qn as f,St as ee,wn as p,xt as m}from"./tv-remote.js";import{t as h}from"./runtime.js";import{$t as g,Gt as _,Ht as v,Mt as y,Ot as b,Qt as x,Tt as S,en as C,jt as w,kt as te,qt as ne,tn as T,wt as E}from"./internal/daemon.js";import{n as D}from"./provider.js";import{_ as O,c as re,d as ie,f as ae,g as k,h as oe,l as se,m as ce,n as le,o as ue,p as de,r as fe,s as pe,u as me,v as he,y as A}from"./selector-runtime.js";import{i as j,n as M,r as N,t as P}from"./interaction-snapshot.js";const F=new Set(c());function I(e){return R({fields:L(e.command),input:e.input??{},data:e.data,controlledFields:F})}function L(e){let t=l(e);if(!t)throw Error(`Missing response data transform descriptor for ${e}`);return t.fields}function R(e){let t=Object.fromEntries(Object.entries(e.data??{}).filter(([t])=>!e.controlledFields.has(t)));for(let[n,r]of Object.entries(e.fields)){let i=e.input[n]===void 0?r.defaultValue:e.input[n];if(i===void 0||r.omitDefault===!0&&i===r.defaultValue){delete t[n];continue}t[n]=i}return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0))}const ge=new Set([`currentUptimeMs`,`gestureEndUptimeMs`,`gestureStartUptimeMs`,`sequenceResults`]);function _e(e){if(e)return Object.fromEntries(Object.entries(e).filter(([e])=>!ge.has(e)))}function z(e){let{source:t,referenceFrame:n,extra:r}=e;if(t.kind===`runner-payload`){let e={targetKind:t.targetKind,...r??{}};return{result:B({data:t.data,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:n,extra:e}),responseData:B({data:t.publicData,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:n,extra:e})}}let{result:i}=t,a=ae(i),o={targetKind:i.kind,...a,...ve(i.settle,e.settleRefsGeneration),...r??{}},s=B({data:i.backendResult,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:o}),c=B({data:t.publicData,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:o}),l=ye(`warning`in i?i.warning:void 0,e.staleRefsWarning);return l&&(s.warning=l,c.warning=l),{result:s,responseData:c}}function ve(e,t){return!e?.diff||t===void 0?{}:{settle:{...e,refsGeneration:t}}}function ye(e,t){return t?e?`${e} ${t}`:t:e}function B(e){let{data:t,fallbackX:n,fallbackY:r,referenceFrame:i,extra:a}=e,o=xe(a,n,r)??(typeof t?.message==`string`?t.message:void 0);return be({...t??{},...n===void 0||r===void 0?{}:{x:n,y:r},...i??{},...a??{},...p(o)})}function be(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function xe(e,t,n){let r=V(e,`text`);if(r!==void 0)return`Filled ${Array.from(r).length} chars`;let i=Se(t,n),a=Ce(e);if(a)return Te(a,e??{},i);if(i)return we(e,i)}function V(e,t){let n=e?.[t];return typeof n==`string`?n:void 0}function Se(e,t){return e===void 0||t===void 0?``:` (${e}, ${t})`}function Ce(e){let t=V(e,`ref`);return t===void 0?V(e,`selector`):`@${t}`}function we(e,t){return e?.gesture===`longpress`?`Long pressed${t}`:`Tapped${t}`}function Te(e,t,n){let r=typeof t.button==`string`?t.button:void 0;return t.gesture===`longpress`?`Long pressed ${e}${n}`:r&&r!==`primary`?`Clicked ${r} ${e}${n}`:`Tapped ${e}${n}`}function H(e,t){return!a(e.device)||e.surface!==`desktop`&&e.surface!==`menubar`||e.surface===`menubar`&&(t===`click`||t===`press`)?null:g(`UNSUPPORTED_OPERATION`,`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}function U(e){let n=e.sessionStore.get(e.sessionName);if(!n)throw new t(`SESSION_NOT_FOUND`,x);return h({backend:Ee({...e,session:n}),...ue(`interaction commands`,{plural:!0}),sessions:b({sessionName:e.sessionName,getSession:()=>n,recordOptions:{includeSnapshot:!0},setRecord:t=>{t.snapshot&&(y(n,t.snapshot),e.sessionStore.set(e.sessionName,n))}})})}function Ee(e){let{req:t,session:n}=e,i=De(n);return{platform:r(n.device),captureSnapshot:async(r,i)=>({snapshot:await e.captureSnapshotForSession(n,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:i?.interactiveOnly===!0,includeRects:i?.includeRects===!0})}),tap:async(r,i)=>W(await _(n.device,`press`,[String(i.x),String(i.y)],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath))),tapTarget:i?.clickRef?async(e,t)=>(await i.clickRef?.(t.ref),{ref:k(t.ref)}):void 0,fill:async(r,i,a)=>W(await _(n.device,`fill`,[String(i.x),String(i.y),a],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath))),fillTarget:i?.fillRef?async(e,t,n,r)=>(await i.fillRef?.(t.ref,n,r),{ref:k(t.ref),text:n,delayMs:r?.delayMs??0}):void 0,longPress:async(r,i,a)=>W(await _(n.device,`longpress`,[String(i.x),String(i.y),...a?.durationMs===void 0?[]:[String(a.durationMs)]],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath))),typeText:async(r,i)=>W(await _(n.device,`type`,[i],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath)))}}function De(e){if(e.device.platform!==`web`)return;let t=D();return t.clickRef||t.fillRef?t:void 0}function W(e){return e&&typeof e==`object`?e:void 0}async function Oe(e){switch(e.req.command){case`press`:return await G(e,`press`);case`click`:return await G(e,`click`);case`longpress`:return await G(e,`longpress`);case`fill`:return await ze(e);default:return null}}async function G(e,t){let{req:n,sessionName:i,sessionStore:a}=e,o=a.get(i);if(!o)return C();let s=t===`click`?`click`:t,c=t===`longpress`?`longpress`:`press`,l=H(o,s);if(l)return l;let u=T(c,o.device);if(u)return u;let f=A(t,n.flags);if(f)return f;let p=d(n.flags),h=m(p);if(t!==`longpress`&&p!==`primary`){let e=ee({commandLabel:s,platform:r(o.device),button:p,count:n.flags?.count,intervalMs:n.flags?.intervalMs,holdMs:n.flags?.holdMs,jitterPx:n.flags?.jitterPx,doubleTap:n.flags?.doubleTap});if(e)return g(e.code,e.message,e.details)}let _=t===`longpress`?ce(n.positionals??[]):oe(n.positionals??[],s);if(!_.ok)return _.response;let v=_.target.kind===`ref`?w({session:o,ref:_.target.ref,mintedGeneration:_.refGeneration}):void 0,y;if(_.target.kind===`ref`){let r=e.refSnapshotFlagGuardResponse(t===`longpress`?`longpress`:`press`,n.flags);if(r)return r;y=await Z(e,o)}let b=Me({session:o,commandLabel:s,target:_.target,flags:n.flags});if(b){let t=await Pe(e,o,b);if(t)return t}let x=t===`longpress`?_.durationMs:void 0;return await X(e,{androidFreshnessBaseline:y,run:async e=>await ke({runtime:e,command:t,target:_.target,sessionName:i,requestId:n.meta?.requestId,clickButton:p,flags:n.flags,durationMs:x}),afterRun:async e=>{o.lease?.leaseProvider||await se(o,ie(_.target,e))},buildPayloads:async r=>{let i=je(r);return await Ae({params:e,session:o,result:r,staleRefsWarning:v,publicData:Y({session:o,command:t===`longpress`?void 0:t,flags:n.flags,data:r.backendResult}),extra:t===`longpress`?{...i===void 0?{}:{durationMs:i},gesture:`longpress`}:h})}})}async function ke(e){let{runtime:t,command:n,target:r,sessionName:i,requestId:a,flags:o}=e,s=O(o);if(n===`longpress`)return await t.interactions.longPress(r,{session:i,requestId:a,durationMs:e.durationMs,settle:s});let c={session:i,requestId:a,button:e.clickButton,count:o?.count,intervalMs:o?.intervalMs,holdMs:o?.holdMs,jitterPx:o?.jitterPx,doubleTap:o?.doubleTap,verify:o?.verify,settle:s};return n===`click`?await t.interactions.click(r,c):await t.interactions.press(r,c)}async function Ae(e){let{params:t,session:n,result:r,publicData:i,extra:a}=e,o=r.kind===`point`?await N({session:n,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession}):M(n.snapshot?.nodes??[]);return z({source:{kind:`runtime`,result:r,publicData:i},referenceFrame:o,extra:a,staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:K(n,r)})}function K(e,t){if(t.settle?.diff)return te(e),e.snapshotGeneration}function je(e){return`durationMs`in e?e.durationMs:void 0}function Me(e){let{session:t,commandLabel:n,target:r,flags:i}=e;return n!==`click`||r.kind!==`selector`||Ne(i)||s(n)&&i?.verify===!0||u(n)&&i?.settle===!0?null:q(t,r.selector,i)}function q(e,t,n){let r=re({session:e,selectorExpression:t});return r?{...r,...n?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}function Ne(e){return e?.count!==void 0||e?.intervalMs!==void 0||e?.holdMs!==void 0||e?.jitterPx!==void 0||e?.doubleTap!==void 0||e?.clickButton!==void 0&&e.clickButton!==`primary`}async function Pe(e,t,n){return await J({params:e,session:t,selector:n,command:`press`,positionals:[],extra:{selector:n.raw},fallbackPhase:`ios_direct_selector_tap_fallback`})}async function J(t){let{params:n,session:r,selector:i,command:a,positionals:s,extra:c,fallbackPhase:l}=t,u=Date.now();try{let e=await _(r.device,a,s,n.req.flags?.out,{...n.contextFromFlags(n.req.flags,r.appBundleId,r.trace?.outPath),directElementSelector:i,surface:r.surface})??{},t=Date.now(),o=Le(e),{result:l,responseData:d}=z({source:{kind:`runner-payload`,targetKind:`selector`,data:e,publicData:Y({session:r,command:Fe(n.req.command,a),flags:n.req.flags,data:e}),point:o},referenceFrame:Re(e),extra:{...c,...Ie(i,e)}});return j({session:r,sessionStore:n.sessionStore,command:n.req.command,positionals:n.req.positionals??[],retryPositionals:$(o),flags:n.req.flags,result:l,responseData:d,actionStartedAt:u,actionFinishedAt:t})}catch(t){return pe(t,{delegateSemanticFailures:i.allowNonHittableCoordinateFallback!==!0})?(o({level:`debug`,phase:l,data:{selector:i.raw,error:t instanceof Error?t.message:String(t)}}),null):{ok:!1,error:e(t)}}}function Y(e){let t=i(e.session.device.platform)?_e(e.data):e.data;return e.command?I({command:e.command,input:e.flags,data:t}):t}function Fe(e,t){return e===`click`||e===`press`||e===`fill`?e:t}function Ie(e,t){if(!e.allowNonHittableCoordinateFallback)return{};let n=t.message===ne;return{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:n,...n?{maestroFallbackReason:`non-hittable-coordinate`}:{}}}function Le(e){let t=typeof e.x==`number`?e.x:void 0,n=typeof e.y==`number`?e.y:void 0;return t!==void 0&&n!==void 0?{x:t,y:n}:{x:0,y:0}}function Re(e){return typeof e.referenceWidth==`number`&&typeof e.referenceHeight==`number`?{referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight}:void 0}async function ze(e){let{req:t,sessionName:n,sessionStore:r}=e,i=r.get(n);if(i){let e=H(i,`fill`);if(e)return e;let t=T(`fill`,i.device);if(t)return t}if(!i)return C();let a=A(`fill`,t.flags);if(a)return a;let o=de(t.positionals??[]);if(!o.ok)return o.response;let s=await Be(e,i,o.target,o.refGeneration);if(s.response)return s.response;let{staleRefsWarning:c}=s;return await Ve(e,i,o.target,o.text)||await X(e,{run:async e=>await e.interactions.fill(o.target,o.text,{session:n,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs,verify:t.flags?.verify,settle:O(t.flags)}),buildPayloads:e=>He({session:i,result:e,text:o.text,flags:t.flags,staleRefsWarning:c})})}async function Be(e,t,n,r){if(n.kind!==`ref`)return{};let i=w({session:t,ref:n.ref,mintedGeneration:r}),a=e.refSnapshotFlagGuardResponse(`fill`,e.req.flags);return a?{response:a,staleRefsWarning:i}:(await Z(e,t),{staleRefsWarning:i})}async function Ve(e,t,n,r){let i=Ue({session:t,target:n,flags:e.req.flags});return i?await We(e,t,i,r):null}function He(e){let{session:t,result:n}=e,r=n.kind===`point`?void 0:M(t.snapshot?.nodes??[]);return z({source:{kind:`runtime`,result:n,publicData:Y({session:t,command:`fill`,flags:e.flags,data:n.backendResult})},referenceFrame:r,extra:{text:e.text},staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:K(t,n)})}function Ue(e){let{session:t,target:n,flags:r}=e;return n.kind!==`selector`||s(`fill`)&&r?.verify===!0||u(`fill`)&&r?.settle===!0?null:q(t,n.selector,r)}async function We(e,t,n,r){return await J({params:e,session:t,selector:n,command:`fill`,positionals:[r],extra:{selector:n.raw,text:r},fallbackPhase:`ios_direct_selector_fill_fallback`})}async function X(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return C();let i=U(e),a=Date.now();try{let{readiness:n,runtimeResult:o}=await Ge(r,e.req.command,async()=>{let e=await t.run(i);return await t.afterRun?.(e),e}),s=Date.now(),{result:c,responseData:l}=await t.buildPayloads(o);if(n.status===`recovered`){let e=typeof l.warning==`string`?`${l.warning} ${n.warning}`:n.warning;c.warning=e,l.warning=e}return j({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],retryPositionals:Ke(e.req.command,o),flags:e.req.flags,result:c,responseData:l,actionStartedAt:a,actionFinishedAt:s,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(e){let t=n(e);if(me(t))throw t;return Q(e)}}async function Ge(e,t,n){if(e.lease?.leaseProvider)return{readiness:{status:`clear`},runtimeResult:await n()};let r=await E({session:e,command:t,phase:`before-command`}),i=await n();return await E({session:e,command:t,phase:`after-command`}),{readiness:r,runtimeResult:i}}async function Z(e,t){if(!v(t))return;let n=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(t,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:`ref-refresh`})}catch(t){o({level:`warn`,phase:`android_ref_snapshot_refresh_failed`,data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return n}function Q(t){return{ok:!1,error:e(t)}}function Ke(e,t){if(!(t.kind===`ref`&&!t.node)&&(e===`click`||e===`press`))return t.point?$(t.point):void 0}function $(e){return[String(e.x),String(e.y)]}async function qe(e){let t=await Oe({...e,captureSnapshotForSession:P,refSnapshotFlagGuardResponse:he});if(t)return t;switch(e.req.command){case f.type:return await Je({...e,captureSnapshotForSession:P});case`get`:return await le(e);case`is`:return await fe(e);default:return null}}async function Je(e){let{sessionName:t,sessionStore:n}=e,r=n.get(t);return r?T(f.type,r.device)||await Ye(r)||await Xe(e,r):C()}async function Ye(e){return e.device.platform===`android`&&e.recording&&(await S({session:e})).status===`failed`?g(`COMMAND_FAILED`,`Android system dialog blocked the recording session`):null}async function Xe(t,n){let{req:r,sessionName:i,sessionStore:a}=t,o=(r.positionals??[]).join(` `),s=U(t),c=Date.now();try{let e=await E({session:n,command:r.command,phase:`before-command`}),t=await s.interactions.typeText(o,{session:i,requestId:r.meta?.requestId,delayMs:r.flags?.delayMs});await E({session:n,command:r.command,phase:`after-command`});let l=Date.now(),u={...t.backendResult??{},text:t.text,delayMs:t.delayMs,...p(t.message??`Typed ${Array.from(t.text).length} chars`)};return e.status===`recovered`&&(u.warning=e.warning),j({session:n,sessionStore:a,command:r.command,positionals:r.positionals??[],flags:r.flags,result:u,responseData:u,actionStartedAt:c,actionFinishedAt:l})}catch(t){return{ok:!1,error:e(t)}}}export{qe as handleInteractionCommands};
@@ -1,2 +1,2 @@
1
- import{F as e,_ as t,m as n,p as r}from"./sdk-contracts.js";import{F as i}from"./sdk-android-adb.js";import{et as a,pt as o,tt as s,ut as c}from"./device-rotation.js";import{n as l}from"./snapshot-quality.js";import{i as u}from"./runner-client.js";import{o as d}from"./helper.js";import{c as f,i as p,n as m,o as h,r as g,s as _,u as v}from"./apps.js";import{n as y,t as b}from"./runner-sequence.js";function x(e,t,n){return{command:`remotePress`,remoteButton:e,...n===void 0?{}:{durationMs:n},...t===void 0?{}:{appBundleId:t}}}function S(e,t,n,r={includeDuration:!0}){let i=w(e.referenceWidth),a=w(e.referenceHeight);if(i===void 0||a===void 0)return T(e,{amount:n?.amount});let o=s({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:i,referenceHeight:a});return T(e,{amount:n?.amount,pixels:o.pixels,durationMs:r?.includeDuration?n?.durationMs:void 0,preferProvidedPixels:!0})}function C(e,t={includeDuration:!0}){return{...e?.amount===void 0?{}:{amount:e.amount},...e?.pixels===void 0?{}:{pixels:e.pixels},...t?.includeDuration&&e?.durationMs!==void 0?{durationMs:e.durationMs}:{}}}function w(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function T(e,t){let{x1:n,y1:r,x2:i,y2:a}=D(e),o=w(e.referenceWidth),s=w(e.referenceHeight),c=E(t,n!==void 0&&i!==void 0?Math.round(Math.abs(i-n)):void 0,r!==void 0&&a!==void 0?Math.round(Math.abs(a-r)):void 0);return{...n===void 0?{}:{x1:n},...r===void 0?{}:{y1:r},...i===void 0?{}:{x2:i},...a===void 0?{}:{y2:a},...o===void 0?{}:{referenceWidth:o},...s===void 0?{}:{referenceHeight:s},...t?.amount===void 0?{}:{amount:t.amount},...c===void 0?{}:{pixels:c},...t?.durationMs===void 0?{}:{durationMs:t.durationMs}}}function E(e,t,n){if(e?.preferProvidedPixels&&e.pixels!==void 0)return e.pixels;if(t!==void 0&&t>0)return t;if(n!==void 0&&n>0)return n}function D(e){let t=w(e.x),n=w(e.y),r=w(e.x2),i=w(e.y2);return{...t===void 0?{}:{x1:t},...n===void 0?{}:{y1:n},...r===void 0?{}:{x2:r},...i===void 0?{}:{y2:i}}}async function O(e,t,n,r,i,a){return S(await e(t,{command:`desktopScroll`,direction:i,...C(a,{includeDuration:!0}),appBundleId:n.appBundleId},r),i,a,{includeDuration:!0})}function k(e){return e===`system`?`backSystem`:`backInApp`}function A(e,t){let n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId,iosXctestrunFile:t.iosXctestrunFile,iosXctestDerivedDataPath:t.iosXctestDerivedDataPath,iosXctestEnvDir:t.iosXctestEnvDir,runnerLeaseContext:t.runnerLeaseContext};return{runnerOpts:n,overrides:{tap:async(r,i)=>await u(e,j(e,t,r,i),n),tapElementSelector:async r=>await u(e,{command:`tap`,selectorKey:r.key,selectorValue:r.value,allowNonHittableCoordinateFallback:r.allowNonHittableCoordinateFallback,appBundleId:t.appBundleId},n),doubleTap:async(r,i)=>{let a=await u(e,b([{kind:`doubleTap`,x:r,y:i}],t.appBundleId),n);return y(a),a},swipe:async(r,i,a,o,s)=>await u(e,N(e,t,r,i,a,o,s,{defaultDurationMs:250,synthesized:M(e)}),n),pan:async(r,i,a,o,s)=>await u(e,N(e,t,r,i,a,o,s,{defaultDurationMs:500,legacyDefaultDurationMs:500,synthesized:M(e)}),n),fling:async(r,i,a,o,s)=>await u(e,N(e,t,r,i,a,o,s,{defaultDurationMs:16,legacyDefaultDurationMs:16,synthesized:M(e)}),n),longPress:async(r,i,a)=>await u(e,{command:`longPress`,x:r,y:i,durationMs:a,appBundleId:t.appBundleId},n),focus:async(r,i)=>await u(e,j(e,t,r,i),n),type:async(r,i)=>{await u(e,{command:`type`,text:r,delayMs:i,textEntryMode:r===`
2
- `?void 0:`append`,appBundleId:t.appBundleId},n)},fillElementSelector:async(r,i,a)=>await u(e,{command:`type`,selectorKey:r.key,selectorValue:r.value,allowNonHittableCoordinateFallback:r.allowNonHittableCoordinateFallback,text:i,delayMs:a,textEntryMode:`replace`,appBundleId:t.appBundleId},n),fill:async(r,i,a,o)=>await u(e,{command:`type`,x:r,y:i,text:a,delayMs:o,textEntryMode:`replace`,appBundleId:t.appBundleId},n),scroll:async(r,i)=>await F(u,e,t,n,r,i),pinch:async(r,i,a)=>{await u(e,{command:`pinch`,scale:r,x:i,y:a,appBundleId:t.appBundleId},n)},rotateGesture:async(r,i,a,o)=>{await u(e,{command:`rotateGesture`,degrees:r,x:i,y:a,velocity:o,appBundleId:t.appBundleId},n)},transformGesture:async r=>await u(e,{command:`transformGesture`,x:r.x,y:r.y,dx:r.dx,dy:r.dy,scale:r.scale,degrees:r.degrees,durationMs:r.durationMs,appBundleId:t.appBundleId},n)}}}function j(e,t,n,r){return{command:`tap`,x:n,y:r,...M(e)?{synthesized:!0}:{},appBundleId:t.appBundleId}}function M(e){return r(e)&&!t(e)}function N(e,n,i,a,o,s,c,l){let u=r(e)&&!t(e)?P(c,l.defaultDurationMs):c??l.legacyDefaultDurationMs;return{command:`drag`,x:i,y:a,x2:o,y2:s,...u===void 0?{}:{durationMs:u},...l.synthesized===!0?{synthesized:!0}:{},appBundleId:n.appBundleId}}function P(e,t){return e===void 0?t:Math.min(1e4,Math.max(16,Math.round(e)))}async function F(e,r,i,s,l,u){return o(u?.durationMs,{invalidMessage:`scroll durationMs must be a non-negative integer at most ${c}`}),t(r)?T(await e(r,x(l,i.appBundleId,u?.durationMs),s),{amount:u?.amount,durationMs:u?.durationMs}):(a(u??{}),n(r)?await O(e,r,i,s,l,u):S(await e(r,{command:`scroll`,direction:l,...C(u),appBundleId:i.appBundleId},s),l,u))}function I(r,a){if(r.appleOs===`watchos`)throw new e(`UNSUPPORTED_PLATFORM`,`watchOS is not supported: XCUITest cannot drive watchOS UI, so this device has no runner backend.`);let{overrides:o,runnerOpts:s}=A(r,a);return{open:(e,t)=>_(r,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,terminateRunningApp:t?.terminateRunningApp,url:t?.url}),openDevice:()=>f(r),close:e=>h(r,e),screenshot:async(e,t)=>{if(n(r)&&t?.surface&&t.surface!==`app`){await d(e,{surface:t.surface,fullscreen:t.fullscreen});return}await v(r,e,{appBundleId:t?.appBundleId,fullscreen:t?.fullscreen,runnerOptions:s,normalizeStatusBar:t?.normalizeStatusBar,skipIosSimulatorBootCheck:t?.skipIosSimulatorBootCheck})},snapshot:async t=>{let n=L(await i(`snapshot_capture`,async()=>await u(r,{command:`snapshot`,appBundleId:t?.appBundleId,interactiveOnly:t?.interactiveOnly,depth:t?.depth,scope:t?.scope,raw:t?.raw},s),{backend:`xctest`})),a=n.nodes??[];if(a.length===0&&r.kind===`simulator`)throw new e(`COMMAND_FAILED`,`XCTest snapshot returned 0 nodes on iOS simulator.`);return{nodes:a,truncated:n.truncated??!1,backend:`xctest`,...n.quality?{quality:n.quality}:{},...!n.quality&&n.message?{warnings:[n.message]}:{}}},back:async e=>{if(t(r)){await u(r,x(`menu`,a.appBundleId),s);return}await u(r,{command:k(e),appBundleId:a.appBundleId},s)},home:async()=>{if(t(r)){await u(r,x(`home`,a.appBundleId),s);return}await u(r,{command:`home`,appBundleId:a.appBundleId},s)},rotate:async e=>{await u(r,{command:`rotate`,orientation:e,appBundleId:a.appBundleId},s)},appSwitcher:async()=>{await u(r,{command:`appSwitcher`,appBundleId:a.appBundleId},s)},readClipboard:()=>g(r),writeClipboard:e=>p(r,e),setSetting:(e,t,n,i)=>m(r,e,t,n,i),...o}}function L(e){return{nodes:Array.isArray(e.nodes)?e.nodes:void 0,truncated:typeof e.truncated==`boolean`?e.truncated:void 0,quality:l(e.snapshotQuality),message:typeof e.message==`string`&&e.message.trim().length>0?e.message:void 0}}export{I as createAppleInteractor};
1
+ import{F as e,_ as t,m as n,p as r}from"./sdk-contracts.js";import{F as i}from"./sdk-android-adb.js";import{a,gt as o,ot as s,st as c,yt as l}from"./tv-remote.js";import{n as u}from"./snapshot-quality.js";import{i as d}from"./runner-client.js";import{o as f}from"./helper.js";import{c as p,i as m,n as h,o as g,r as _,s as v,u as y}from"./apps.js";import{n as b,t as x}from"./runner-sequence.js";function S(e,t,n){return{command:`remotePress`,remoteButton:e,...n===void 0?{}:{durationMs:n},...t===void 0?{}:{appBundleId:t}}}function C(e,t,n,r={includeDuration:!0}){let i=T(e.referenceWidth),a=T(e.referenceHeight);if(i===void 0||a===void 0)return E(e,{amount:n?.amount});let o=c({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:i,referenceHeight:a});return E(e,{amount:n?.amount,pixels:o.pixels,durationMs:r?.includeDuration?n?.durationMs:void 0,preferProvidedPixels:!0})}function w(e,t={includeDuration:!0}){return{...e?.amount===void 0?{}:{amount:e.amount},...e?.pixels===void 0?{}:{pixels:e.pixels},...t?.includeDuration&&e?.durationMs!==void 0?{durationMs:e.durationMs}:{}}}function T(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function E(e,t){let{x1:n,y1:r,x2:i,y2:a}=O(e),o=T(e.referenceWidth),s=T(e.referenceHeight),c=D(t,n!==void 0&&i!==void 0?Math.round(Math.abs(i-n)):void 0,r!==void 0&&a!==void 0?Math.round(Math.abs(a-r)):void 0);return{...n===void 0?{}:{x1:n},...r===void 0?{}:{y1:r},...i===void 0?{}:{x2:i},...a===void 0?{}:{y2:a},...o===void 0?{}:{referenceWidth:o},...s===void 0?{}:{referenceHeight:s},...t?.amount===void 0?{}:{amount:t.amount},...c===void 0?{}:{pixels:c},...t?.durationMs===void 0?{}:{durationMs:t.durationMs}}}function D(e,t,n){if(e?.preferProvidedPixels&&e.pixels!==void 0)return e.pixels;if(t!==void 0&&t>0)return t;if(n!==void 0&&n>0)return n}function O(e){let t=T(e.x),n=T(e.y),r=T(e.x2),i=T(e.y2);return{...t===void 0?{}:{x1:t},...n===void 0?{}:{y1:n},...r===void 0?{}:{x2:r},...i===void 0?{}:{y2:i}}}async function k(e,t,n,r,i,a){return C(await e(t,{command:`desktopScroll`,direction:i,...w(a,{includeDuration:!0}),appBundleId:n.appBundleId},r),i,a,{includeDuration:!0})}function A(e){return e===`system`?`backSystem`:`backInApp`}function j(e,t){let n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId,iosXctestrunFile:t.iosXctestrunFile,iosXctestDerivedDataPath:t.iosXctestDerivedDataPath,iosXctestEnvDir:t.iosXctestEnvDir,runnerLeaseContext:t.runnerLeaseContext};return{runnerOpts:n,overrides:{tap:async(r,i)=>await d(e,M(e,t,r,i),n),tapElementSelector:async r=>await d(e,{command:`tap`,selectorKey:r.key,selectorValue:r.value,allowNonHittableCoordinateFallback:r.allowNonHittableCoordinateFallback,appBundleId:t.appBundleId},n),doubleTap:async(r,i)=>{let a=await d(e,x([{kind:`doubleTap`,x:r,y:i}],t.appBundleId),n);return b(a),a},swipe:async(r,i,a,o,s)=>await d(e,P(e,t,r,i,a,o,s,{defaultDurationMs:250,synthesized:N(e)}),n),pan:async(r,i,a,o,s)=>await d(e,P(e,t,r,i,a,o,s,{defaultDurationMs:500,legacyDefaultDurationMs:500,synthesized:N(e)}),n),fling:async(r,i,a,o,s)=>await d(e,P(e,t,r,i,a,o,s,{defaultDurationMs:16,legacyDefaultDurationMs:16,synthesized:N(e)}),n),longPress:async(r,i,a)=>await d(e,{command:`longPress`,x:r,y:i,durationMs:a,appBundleId:t.appBundleId},n),focus:async(r,i)=>await d(e,M(e,t,r,i),n),type:async(r,i)=>{await d(e,{command:`type`,text:r,delayMs:i,textEntryMode:r===`
2
+ `?void 0:`append`,appBundleId:t.appBundleId},n)},fillElementSelector:async(r,i,a)=>await d(e,{command:`type`,selectorKey:r.key,selectorValue:r.value,allowNonHittableCoordinateFallback:r.allowNonHittableCoordinateFallback,text:i,delayMs:a,textEntryMode:`replace`,appBundleId:t.appBundleId},n),fill:async(r,i,a,o)=>await d(e,{command:`type`,x:r,y:i,text:a,delayMs:o,textEntryMode:`replace`,appBundleId:t.appBundleId},n),scroll:async(r,i)=>await I(d,e,t,n,r,i),pinch:async(r,i,a)=>{await d(e,{command:`pinch`,scale:r,x:i,y:a,appBundleId:t.appBundleId},n)},rotateGesture:async(r,i,a,o)=>{await d(e,{command:`rotateGesture`,degrees:r,x:i,y:a,velocity:o,appBundleId:t.appBundleId},n)},transformGesture:async r=>await d(e,{command:`transformGesture`,x:r.x,y:r.y,dx:r.dx,dy:r.dy,scale:r.scale,degrees:r.degrees,durationMs:r.durationMs,appBundleId:t.appBundleId},n)}}}function M(e,t,n,r){return{command:`tap`,x:n,y:r,...N(e)?{synthesized:!0}:{},appBundleId:t.appBundleId}}function N(e){return r(e)&&!t(e)}function P(e,n,i,a,o,s,c,l){let u=r(e)&&!t(e)?F(c,l.defaultDurationMs):c??l.legacyDefaultDurationMs;return{command:`drag`,x:i,y:a,x2:o,y2:s,...u===void 0?{}:{durationMs:u},...l.synthesized===!0?{synthesized:!0}:{},appBundleId:n.appBundleId}}function F(e,t){return e===void 0?t:Math.min(1e4,Math.max(16,Math.round(e)))}async function I(e,r,i,a,c,u){return l(u?.durationMs,{invalidMessage:`scroll durationMs must be a non-negative integer at most ${o}`}),t(r)?E(await e(r,S(c,i.appBundleId,u?.durationMs),a),{amount:u?.amount,durationMs:u?.durationMs}):(s(u??{}),n(r)?await k(e,r,i,a,c,u):C(await e(r,{command:`scroll`,direction:c,...w(u),appBundleId:i.appBundleId},a),c,u))}function L(n,r){if(n.appleOs===`watchos`)throw new e(`UNSUPPORTED_PLATFORM`,`watchOS is not supported: XCUITest cannot drive watchOS UI, so this device has no runner backend.`);let{overrides:o,runnerOpts:s}=j(n,r);return{open:(e,t)=>v(n,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,terminateRunningApp:t?.terminateRunningApp,url:t?.url}),openDevice:()=>p(n),close:e=>g(n,e),screenshot:(e,t)=>R(n,e,t,s),snapshot:async t=>{let r=B(await i(`snapshot_capture`,async()=>await d(n,{command:`snapshot`,appBundleId:t?.appBundleId,interactiveOnly:t?.interactiveOnly,depth:t?.depth,scope:t?.scope,raw:t?.raw},s),{backend:`xctest`})),a=r.nodes??[];if(a.length===0&&n.kind===`simulator`)throw new e(`COMMAND_FAILED`,`XCTest snapshot returned 0 nodes on iOS simulator.`);return{nodes:a,truncated:r.truncated??!1,backend:`xctest`,...r.quality?{quality:r.quality}:{},...!r.quality&&r.message?{warnings:[r.message]}:{}}},back:async e=>{if(t(n)){await d(n,S(`menu`,r.appBundleId),s);return}await d(n,{command:A(e),appBundleId:r.appBundleId},s)},home:async()=>{if(t(n)){await d(n,S(`home`,r.appBundleId),s);return}await d(n,{command:`home`,appBundleId:r.appBundleId},s)},rotate:async e=>{await d(n,{command:`rotate`,orientation:e,appBundleId:r.appBundleId},s)},appSwitcher:async()=>{await d(n,{command:`appSwitcher`,appBundleId:r.appBundleId},s)},tvRemote:async(e,t)=>{await d(n,S(a(e),r.appBundleId,t),s)},readClipboard:()=>_(n),writeClipboard:e=>m(n,e),setSetting:(e,t,r,i)=>h(n,e,t,r,i),...o}}async function R(e,t,n={},r){if(z(e,n.surface)){await f(t,{surface:n.surface,fullscreen:n.fullscreen});return}await y(e,t,{appBundleId:n.appBundleId,pixelDensity:n.pixelDensity,fullscreen:n.fullscreen,runnerOptions:r,normalizeStatusBar:n.normalizeStatusBar,skipIosSimulatorBootCheck:n.skipIosSimulatorBootCheck})}function z(e,t){return n(e)&&t!==void 0&&t!==`app`}function B(e){return{nodes:Array.isArray(e.nodes)?e.nodes:void 0,truncated:typeof e.truncated==`boolean`?e.truncated:void 0,quality:u(e.snapshotQuality),message:typeof e.message==`string`&&e.message.trim().length>0?e.message:void 0}}export{L as createAppleInteractor};
@@ -1,2 +1,2 @@
1
- const e=process.argv.slice(2);t(e)||(e[0]===`mcp`&&!e.includes(`--help`)&&!e.includes(`-h`)?import(`../server.js`).then(({runAgentDeviceMcpServer:e})=>e()).catch(m):p(e));function t(e){return n(e)||r(e)||i(e)}function n(e){return e.length!==1||!f(e[0])?!1:(process.stdout.write(`0.19.0
1
+ const e=process.argv.slice(2);t(e)||(e[0]===`mcp`&&!e.includes(`--help`)&&!e.includes(`-h`)?import(`../server.js`).then(({runAgentDeviceMcpServer:e})=>e()).catch(m):p(e));function t(e){return n(e)||r(e)||i(e)}function n(e){return e.length!==1||!f(e[0])?!1:(process.stdout.write(`0.19.2
2
2
  `),!0)}function r(e){return e.length===0?(import(`../cli-help.js`).then(({buildUsageText:e})=>{process.stdout.write(`${e()}\n`),process.exit(1)}).catch(m),!0):!1}function i(e){let t=a(e);return t===void 0?!1:(import(`../cli-help.js`).then(({buildCommandUsageText:n,buildUsageText:r})=>{if(t===null){process.stdout.write(`${r()}\n`);return}let i=n(l(t));if(i){process.stdout.write(i);return}p(e)}).catch(m),!0)}function a(e){switch(e.length){case 1:return o(e[0]);case 2:return s(e[0],e[1]);default:return}}function o(e){return e===`help`||d(e)?null:void 0}function s(e,t){return u(e)?t:c(e,t)}function c(e,t){return d(t)?e:void 0}function l(e){return e===`long-press`?`longpress`:e===`metrics`?`perf`:e}function u(e){return e===`help`}function d(e){return e===`--help`||e===`-h`}function f(e){return e===`--version`||e===`-V`}function p(e){import(`../cli.js`).then(({runCli:t})=>t(e)).catch(m)}function m(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}export{};