agent-device 0.18.1 → 0.18.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.1.apk → agent-device-android-multitouch-helper-0.18.3.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.3.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.1.manifest.json → agent-device-android-multitouch-helper-0.18.3.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.1.apk → agent-device-android-snapshot-helper-0.18.3.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.3.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.1.manifest.json → agent-device-android-snapshot-helper-0.18.3.manifest.json} +6 -6
- package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +2 -1
- package/dist/src/1986.js +1 -1
- package/dist/src/2948.js +16 -16
- package/dist/src/3340.js +8 -8
- package/dist/src/4428.js +3 -3
- package/dist/src/495.js +5 -5
- package/dist/src/6849.js +1 -1
- package/dist/src/7871.js +1 -1
- package/dist/src/8184.js +1 -1
- package/dist/src/8414.js +2 -2
- package/dist/src/8875.js +4 -1
- package/dist/src/9581.js +3 -3
- package/dist/src/9624.js +1 -1
- package/dist/src/9722.js +38 -37
- package/dist/src/android.js +1 -1
- package/dist/src/apps.js +9 -9
- package/dist/src/audio-probe.js +1 -1
- package/dist/src/batch.d.ts +1 -1
- package/dist/src/cli-help.js +15 -8
- package/dist/src/cli.js +23 -23
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/devices.js +1 -1
- package/dist/src/devices~1.js +1 -1
- package/dist/src/index.d.ts +61 -16
- package/dist/src/input-actions.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/record-trace-recording.js +3 -3
- package/dist/src/remote-config.d.ts +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +8 -4
- package/dist/src/session.js +11 -11
- package/dist/src/simulator.js +2 -2
- package/dist/src/snapshot.js +2 -2
- package/dist/src/web.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/skills/agent-device/SKILL.md +2 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.1.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.1.apk.sha256 +0 -1
- package/dist/src/432.js +0 -4
package/dist/src/contracts.d.ts
CHANGED
|
@@ -172,7 +172,7 @@ export declare function normalizeError(err: unknown, context?: {
|
|
|
172
172
|
logPath?: string;
|
|
173
173
|
}): NormalizedError;
|
|
174
174
|
|
|
175
|
-
declare const PLATFORM_SELECTORS: readonly ["
|
|
175
|
+
declare const PLATFORM_SELECTORS: readonly ["apple", "android", "linux", "web", "ios", "macos"];
|
|
176
176
|
|
|
177
177
|
declare type PlatformSelector = (typeof PLATFORM_SELECTORS)[number];
|
|
178
178
|
|
package/dist/src/devices.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{promises as e}from"node:fs";import t from"node:os";import i from"node:path";import{AppError as r}from"./485.js";import{sortAppleDevicesForSelection as
|
|
1
|
+
import{promises as e}from"node:fs";import t from"node:os";import i from"node:path";import{AppError as r}from"./485.js";import{isIosFamily as o,sortAppleDevicesForSelection as n}from"./6849.js";import{buildHostMacDevice as s}from"./devices~1.js";import{runXcrun as l,resolveAppleToolProvider as a,buildSimctlArgs as u}from"./9722.js";import{markSimulatorBooted as c}from"./simulator.js";import{resolveIosSimulatorDeviceSetPath as d}from"./3340.js";let p=/^(iphone|ipad|ipod|appletv|realitydevice)/i,f=/ipad/i,m=/\b(apple vision|vision pro|xros|visionos|realitydevice)\b/i,v=/\b(iphone|ipad|ipod)\b/i,_=/^appletv/i,h=["apple tv","appletv","tvos"],S=/^==\s*(.+?)\s*==$/,w=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function P(e){return(e??"").trim().toLowerCase()}function y(e){return P(e.hardwareProperties?.platform)}function C(e){return e.includes("tvos")}function b(e){let t=P(e);return h.some(e=>t.includes(e))}function O(e,t){return"tv"===e?"tvos":t.some(e=>m.test(e))?"visionos":t.some(e=>f.test(e))?"ipados":"ios"}function A(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function N(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function K(e={}){let t,i,r=d(e.simulatorSetPath),o=e.target;try{t=await l(u(["list","devices","-j"],{simulatorSetPath:r}))}catch{return null}try{i=JSON.parse(t.stdout)}catch{return null}return n(M(i,r)).find(e=>!o||e.target===o)??null}function M(e,t){let i=[];for(let[r,o]of Object.entries(e.devices))if(function(e){let t=P(e);return t.includes("ios")||t.includes("tvos")||t.includes("xros")||t.includes("visionos")}(r))for(let e of o){if(!e.isAvailable)continue;let o=C(P(r))?"tv":"mobile",n={platform:"apple",id:e.udid,name:e.name,kind:"simulator",target:o,appleOs:O(o,[e.deviceTypeIdentifier??"",e.name]),booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}};n.booted&&c(n),i.push(n)}return i}function x(e,t){let i=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)i.has(e.id)||(i.add(e.id),r.push(e));return r}async function E(){let r=null;try{r=i.join(t.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let o=await l(["devicectl","list","devices","--json-output",r],{allowFailure:!0,timeoutMs:8e3});if(0!==o.exitCode)return[];let n=await e.readFile(r,"utf8");return function(e){let t=[];for(let i of e.result?.devices??[]){if(!function(e){var t,i;let r=y(e);return!!(r.includes("ios")||r.includes("tvos")||(t=r).includes("xros")||t.includes("visionos"))||(i=N(e),!!p.test(i.trim())||A(e).some(b))}(i))continue;let e=i.hardwareProperties?.udid??i.identifier??"",r=i.name??i.deviceProperties?.name??e;if(!e)continue;let o=function(e){var t;return C(y(e))?"tv":(t=N(e),_.test(t.trim())||A(e).some(b))?"tv":"mobile"}(i);t.push({platform:"apple",id:e,name:r,kind:"device",target:o,appleOs:O(o,[N(i),...A(i)]),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{r&&await e.rm(r,{force:!0}).catch(()=>{})}}async function R(){try{let e=await l(["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],i=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let o=S.exec(e);if(o){i=o[1]?.trim()??null;continue}if("Devices"!==i)continue;let n=w.exec(e),s=n?.groups?.id?.trim()??"",l=n?.groups?.name?.trim()??"";if(!s||!l)continue;let a=function(e){return b(e)?"tv":v.test(e.trim())||m.test(e)?"mobile":null}(l);a&&t.push({platform:"apple",id:s,name:l,kind:"device",target:a,appleOs:O(a,[l]),booted:!0})}return t}(e.stdout)}catch{return[]}}async function T(e={}){if("darwin"!==process.platform)throw new r("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await a().whichCommand("xcrun"))throw new r("TOOL_MISSING","xcrun not found in PATH");let t=d(e.simulatorSetPath),i=await l(u(["list","devices","-j"],{simulatorSetPath:t})),c=[];try{let e=JSON.parse(i.stdout);c=M(e,t)}catch(e){throw new r("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(c.push(s()),e.udid&&c.some(t=>o(t)&&t.id===e.udid))return c;if(t)return n(c);let[p,f]=await Promise.all([E(),R()]);return c=x(c,p),n(x(c,f))}export{K as findBootableIosSimulator,T as listAppleDevices};
|
package/dist/src/devices~1.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"node:os";function e(){return{platform:"
|
|
1
|
+
import o from"node:os";function e(){return{platform:"apple",id:"host-macos-local",name:o.hostname(),kind:"device",target:"desktop",appleOs:"macos",booted:!0}}async function t(){return[e()]}export{e as buildHostMacDevice,t as listMacosDevices};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
declare type AgentArtifactsResult = CloudArtifactsResult | DaemonArtifactsResult;
|
|
2
|
+
|
|
1
3
|
declare type AgentDeviceClient = {
|
|
2
4
|
command: AgentDeviceCommandClient;
|
|
3
5
|
devices: {
|
|
@@ -11,7 +13,7 @@ declare type AgentDeviceClient = {
|
|
|
11
13
|
close: (options?: AgentDeviceRequestOverrides & {
|
|
12
14
|
shutdown?: boolean;
|
|
13
15
|
}) => Promise<SessionCloseResult>;
|
|
14
|
-
artifacts: (options?: CloudArtifactsOptions) => Promise<
|
|
16
|
+
artifacts: (options?: CloudArtifactsOptions) => Promise<AgentArtifactsResult>;
|
|
15
17
|
};
|
|
16
18
|
apps: {
|
|
17
19
|
install: (options: AppInstallOptions) => Promise<AppDeployResult>;
|
|
@@ -124,12 +126,17 @@ declare type AgentDeviceCommandClient = {
|
|
|
124
126
|
declare type AgentDeviceDaemonTransport = (req: Omit<DaemonRequest, 'token'>) => Promise<DaemonResponse>;
|
|
125
127
|
|
|
126
128
|
declare type AgentDeviceDevice = {
|
|
127
|
-
platform:
|
|
129
|
+
platform: PublicPlatform;
|
|
128
130
|
target: DeviceTarget;
|
|
129
131
|
kind: DeviceKind;
|
|
130
132
|
id: string;
|
|
131
133
|
name: string;
|
|
132
134
|
booted?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Additive Apple-OS discriminant (iPhone/iPad/tvOS/visionOS/macOS). Present only for
|
|
137
|
+
* Apple devices; `platform` still carries the leaf (`ios`/`macos`).
|
|
138
|
+
*/
|
|
139
|
+
appleOs?: AppleOS;
|
|
133
140
|
identifiers: AgentDeviceIdentifiers;
|
|
134
141
|
ios?: {
|
|
135
142
|
udid: string;
|
|
@@ -172,10 +179,15 @@ declare type AgentDeviceSession = {
|
|
|
172
179
|
};
|
|
173
180
|
|
|
174
181
|
declare type AgentDeviceSessionDevice = {
|
|
175
|
-
platform:
|
|
182
|
+
platform: PublicPlatform;
|
|
176
183
|
target: DeviceTarget;
|
|
177
184
|
id: string;
|
|
178
185
|
name: string;
|
|
186
|
+
/**
|
|
187
|
+
* Additive Apple-OS discriminant (iPhone/iPad/tvOS/visionOS/macOS). Present only for
|
|
188
|
+
* Apple devices; `platform` still carries the leaf (`ios`/`macos`).
|
|
189
|
+
*/
|
|
190
|
+
appleOs?: AppleOS;
|
|
179
191
|
identifiers: AgentDeviceIdentifiers;
|
|
180
192
|
ios?: {
|
|
181
193
|
udid: string;
|
|
@@ -242,7 +254,7 @@ declare type AppDeployOptions = AgentDeviceRequestOverrides & AgentDeviceSelecti
|
|
|
242
254
|
declare type AppDeployResult = {
|
|
243
255
|
app: string;
|
|
244
256
|
appPath: string;
|
|
245
|
-
platform:
|
|
257
|
+
platform: PublicPlatform;
|
|
246
258
|
appId?: string;
|
|
247
259
|
bundleId?: string;
|
|
248
260
|
package?: string;
|
|
@@ -288,6 +300,10 @@ declare type AppInstallOptions = AgentDeviceRequestOverrides & AgentDeviceSelect
|
|
|
288
300
|
appPath: string;
|
|
289
301
|
};
|
|
290
302
|
|
|
303
|
+
declare const APPLE_OS_VALUES: readonly ['ios', 'ipados', 'tvos', 'watchos', 'visionos', 'macos'];
|
|
304
|
+
|
|
305
|
+
declare type AppleOS = (typeof APPLE_OS_VALUES)[number];
|
|
306
|
+
|
|
291
307
|
declare type AppListOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & {
|
|
292
308
|
appsFilter?: AppsFilter;
|
|
293
309
|
};
|
|
@@ -444,11 +460,11 @@ declare type BatchStepResult = {
|
|
|
444
460
|
/**
|
|
445
461
|
* Closed result of the `boot` command. Mirrors the daemon handler's only
|
|
446
462
|
* success return EXACTLY (src/daemon/handlers/session-state.ts) — the fixed
|
|
447
|
-
* object literal `{ platform, target, device, id, kind, booted }
|
|
448
|
-
*
|
|
463
|
+
* object literal `{ platform, target, device, id, kind, booted }` plus the
|
|
464
|
+
* additive `appleOs` discriminant, emitted only for Apple devices.
|
|
449
465
|
*/
|
|
450
466
|
declare type BootCommandResult = {
|
|
451
|
-
platform:
|
|
467
|
+
platform: PublicPlatform;
|
|
452
468
|
target: DeviceTarget;
|
|
453
469
|
/** Human-readable device name (`device.name`). */
|
|
454
470
|
device: string;
|
|
@@ -457,6 +473,12 @@ declare type BootCommandResult = {
|
|
|
457
473
|
kind: DeviceKind;
|
|
458
474
|
/** Always `true` on the success path. */
|
|
459
475
|
booted: true;
|
|
476
|
+
/**
|
|
477
|
+
* Additive Apple-OS discriminant (`device.appleOs`): iPhone/iPad/tvOS/visionOS/macOS.
|
|
478
|
+
* Present only for Apple devices; absent for non-Apple platforms. `platform` stays the
|
|
479
|
+
* leaf (`ios`/`macos`) — this is an extra field, not a replacement.
|
|
480
|
+
*/
|
|
481
|
+
appleOs?: AppleOS;
|
|
460
482
|
};
|
|
461
483
|
|
|
462
484
|
declare type CaptureDiffOptions = DeviceCommandBaseOptions & Pick<CaptureSnapshotOptions, 'interactiveOnly' | 'depth' | 'scope' | 'raw'> & {
|
|
@@ -661,6 +683,22 @@ declare type DaemonArtifact = {
|
|
|
661
683
|
path?: string;
|
|
662
684
|
};
|
|
663
685
|
|
|
686
|
+
declare type DaemonArtifactInventoryEntry = {
|
|
687
|
+
id: string;
|
|
688
|
+
filename: string;
|
|
689
|
+
mimeType: string;
|
|
690
|
+
sizeBytes: number;
|
|
691
|
+
createdAt: string;
|
|
692
|
+
expiresAt: string;
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
declare type DaemonArtifactsResult = {
|
|
696
|
+
source: 'daemon';
|
|
697
|
+
status: 'ready';
|
|
698
|
+
artifacts: DaemonArtifactInventoryEntry[];
|
|
699
|
+
message?: string;
|
|
700
|
+
};
|
|
701
|
+
|
|
664
702
|
declare type DaemonError = {
|
|
665
703
|
code: string;
|
|
666
704
|
message: string;
|
|
@@ -1183,11 +1221,7 @@ declare type PinchOptions = DeviceCommandBaseOptions & {
|
|
|
1183
1221
|
y?: number;
|
|
1184
1222
|
};
|
|
1185
1223
|
|
|
1186
|
-
declare
|
|
1187
|
-
|
|
1188
|
-
declare const PLATFORM_SELECTORS: readonly ["ios", "macos", "android", "linux", "web", "apple"];
|
|
1189
|
-
|
|
1190
|
-
declare const PLATFORMS: readonly ['ios', 'macos', 'android', 'linux', 'web'];
|
|
1224
|
+
declare const PLATFORM_SELECTORS: readonly ["apple", "android", "linux", "web", "ios", "macos"];
|
|
1191
1225
|
|
|
1192
1226
|
declare type PlatformSelector = (typeof PLATFORM_SELECTORS)[number];
|
|
1193
1227
|
|
|
@@ -1232,6 +1266,10 @@ declare type PressCommandResult = ResolvedInteractionTarget & {
|
|
|
1232
1266
|
|
|
1233
1267
|
declare type PressOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & RepeatedPressOptions;
|
|
1234
1268
|
|
|
1269
|
+
declare const PUBLIC_PLATFORMS: readonly ['ios', 'macos', 'android', 'linux', 'web'];
|
|
1270
|
+
|
|
1271
|
+
declare type PublicPlatform = (typeof PUBLIC_PLATFORMS)[number];
|
|
1272
|
+
|
|
1235
1273
|
declare type PublicSnapshotCaptureAnnotations = Pick<SnapshotCaptureAnnotations, 'androidSnapshot' | 'warnings'> & {
|
|
1236
1274
|
snapshotQuality?: SnapshotQualityVerdict;
|
|
1237
1275
|
};
|
|
@@ -1534,11 +1572,12 @@ declare type SettingsUpdateOptions = (DeviceCommandBaseOptions & {
|
|
|
1534
1572
|
/**
|
|
1535
1573
|
* Closed result of the `shutdown` command. Mirrors the daemon handler's success
|
|
1536
1574
|
* return EXACTLY (src/daemon/handlers/session-state.ts) — the fixed object
|
|
1537
|
-
* literal `{ platform, target, device, id, kind, shutdown }
|
|
1538
|
-
* field is the raw
|
|
1575
|
+
* literal `{ platform, target, device, id, kind, shutdown }` plus the additive
|
|
1576
|
+
* `appleOs` discriminant (Apple devices only). The `shutdown` field is the raw
|
|
1577
|
+
* {@link TargetShutdownResult} from `shutdownDeviceTarget`.
|
|
1539
1578
|
*/
|
|
1540
1579
|
declare type ShutdownCommandResult = {
|
|
1541
|
-
platform:
|
|
1580
|
+
platform: PublicPlatform;
|
|
1542
1581
|
target: DeviceTarget;
|
|
1543
1582
|
/** Human-readable device name (`device.name`). */
|
|
1544
1583
|
device: string;
|
|
@@ -1546,6 +1585,12 @@ declare type ShutdownCommandResult = {
|
|
|
1546
1585
|
id: string;
|
|
1547
1586
|
kind: DeviceKind;
|
|
1548
1587
|
shutdown: TargetShutdownResult;
|
|
1588
|
+
/**
|
|
1589
|
+
* Additive Apple-OS discriminant (`device.appleOs`): iPhone/iPad/tvOS/visionOS/macOS.
|
|
1590
|
+
* Present only for Apple devices; absent for non-Apple platforms. `platform` stays the
|
|
1591
|
+
* leaf (`ios`/`macos`) — this is an extra field, not a replacement.
|
|
1592
|
+
*/
|
|
1593
|
+
appleOs?: AppleOS;
|
|
1549
1594
|
};
|
|
1550
1595
|
|
|
1551
1596
|
declare type SnapshotCaptureAnalysis = {
|
|
@@ -1600,7 +1645,7 @@ declare type SnapshotTimingStats = {
|
|
|
1600
1645
|
p95Ms: number;
|
|
1601
1646
|
maxMs: number;
|
|
1602
1647
|
slowThresholdMs: number;
|
|
1603
|
-
platform?:
|
|
1648
|
+
platform?: PublicPlatform;
|
|
1604
1649
|
backends?: Record<string, number>;
|
|
1605
1650
|
};
|
|
1606
1651
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{emitDiagnostic as t}from"./
|
|
1
|
+
import{emitDiagnostic as t}from"./8875.js";import{runAndroidAdb as e,resolveAndroidTextInjector as n}from"./3340.js";import{getAndroidKeyboardState as a,isAndroidInputMethodOwnedNode as r}from"./9624.js";import{captureAndroidUiHierarchyXml as i,androidUiNodes as o}from"./9722.js";import{AppError as u}from"./485.js";import{buildScrollGesturePlan as l}from"./2948.js";import{sleep as c}from"./5560.js";function s(t){var e;return!!t&&(!!t.password||!!(e=t.text)&&Array.from(e).every(f))}function d(t){if(!t)return null;let e=s(t);return{...t,text:e?null:t.text,...e?{textRedacted:!0}:{}}}function f(t){return"•"===t||"*"===t||"●"===t}async function p(t,e,n,a){let r=null,i=null,o=await m(t);for(let u of[0,150,350]){u>0&&await c(u);let l=await g(t,e,n,a,o);if(r=l,"ime_capture"===l.reason)return l;i=l.ok?l:null}return i??r??{ok:!1,actual:null,reason:"text_mismatch",targetInput:null,actualInput:null}}async function h(t,e,n){var a,r,o;return a=await i(t),r=e,o=n,w(a,r,o).actualInput?.text??null}async function g(t,e,n,a,r){return function(t,e,n,a,r={}){var i,o;let u,l=w(t,e,n,r);return!function(t){let{targetInput:e,actualInput:n}=t;return!!e&&!!n&&n!==e&&n.inputMethodOwned&&!e.inputMethodOwned}(l)?function(t,e){let n=t.actualInput;if(!n||!s(n))return null;let a=n.text??null,r=Array.from(a??"").length,i=Array.from(e).length,o=null!==a&&r>0&&i>0&&r===i;return{ok:o,actual:a,reason:o?void 0:"masked_unverified",masked:!0,targetInput:t.targetInput,actualInput:n}}(l,a)??(i=l,o=a,{ok:function(t,e){if(t===e)return!0;let n=y(t),a=y(e);return!!n&&!!a&&!!(n===a||function(t,e){if(t.length!==e.length||0===t.length||t.slice(1)!==e.slice(1))return!1;let n=t[0],a=e[0];return!!n&&!!a&&a.toLowerCase()===a&&n===a.toUpperCase()}(n,a))}(u=i.actualInput?.text??null,o),actual:u,reason:"text_mismatch",targetInput:i.targetInput,actualInput:i.actualInput}):{ok:!1,actual:l.actualInput?.text??null,reason:"ime_capture",targetInput:l.targetInput,actualInput:l.actualInput}}(await i(t),e,n,a,r)}function w(t,e,n,a={}){var i;let u,l={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let i of o(t)){let t=function(t,e){if(!t.rect)return null;let n=t.text??"",a=Math.max(1,t.rect.width*t.rect.height);return{text:n||null,className:t.className,resourceId:t.resourceId,packageName:t.packageName,rect:t.rect,focused:t.focused??!1,password:!0===t.password,inputMethodOwned:r({packageName:t.packageName,resourceId:t.resourceId,activeInputMethodPackage:e.activeInputMethodPackage}),area:a,editText:function(t){let e=t.toLowerCase();return e.includes("edittext")||e.includes("textfield")}(t.className??"")}}(i,a);t&&function(t,e,n,a){var r,i,o;let u=(r=e.rect,i=n,o=a,i>=r.x&&i<=r.x+r.width&&o>=r.y&&o<=r.y+r.height);if(u&&e.editText&&(t.editAtPoint=_(t.editAtPoint,e)),e.focused&&e.editText){t.focusedEdit=_(t.focusedEdit,e);return}u&&e.text&&(t.anyAtPoint=_(t.anyAtPoint,e))}(l,t,e,n)}return{targetInput:u=(i=l).editAtPoint??i.anyAtPoint,actualInput:(i.focusedEdit?.text?i.focusedEdit:null)??u}}function y(t){return(t??"").replace(/\s+/g," ").trim()}async function m(e){try{return{activeInputMethodPackage:(await a(e)).inputMethodPackage}}catch(e){return t({level:"warn",phase:"android_fill_verification_input_method_probe_failed",data:{error:e instanceof Error?e.message:String(e)}}),{}}}function _(t,e){return t&&t.area<e.area?t:e}async function A(t,n,a){await e(t,["shell","input","tap",String(n),String(a)])}async function x(t,n,a,r,i,o=250){await e(t,["shell","input","swipe",String(n),String(a),String(r),String(i),String(o)])}async function I(t){await e(t,["shell","input","keyevent","4"])}async function M(t){await e(t,["shell","input","keyevent","3"])}async function k(t){await e(t,["shell","input","keyevent","ENTER"])}async function S(t,n){let a=function(t){switch(t){case"portrait":return"0";case"landscape-left":return"1";case"portrait-upside-down":return"2";case"landscape-right":return"3";default:throw new u("INVALID_ARGS",`Unsupported Android rotation: ${t}`)}}(n);await e(t,["shell","settings","put","system","accelerometer_rotation","0"]),await e(t,["shell","settings","put","system","user_rotation",a])}async function v(t){await e(t,["shell","input","keyevent","187"])}async function E(t,n,a,r=800){await e(t,["shell","input","swipe",String(n),String(a),String(n),String(a),String(r)])}async function C(t,e,a=0){let r=n(t);if(r){await r({action:"type",text:e,delayMs:a}),F("type","provider-native",e);return}(U(e),await K(t,"type"),a>0&&Array.from(e).length>1)?await L(t,{action:"type",text:e,chunkSize:1,delayMs:a}):await L(t,{action:"type",text:e,chunkSize:O,delayMs:0})}async function P(t,e,n){await A(t,e,n)}async function N(t,e,a,r,i=0){let o=n(t);if(o){await o({action:"fill",target:{x:e,y:a},text:r,delayMs:i}),F("fill","provider-native",r);let n=await p(t,e,a,r);if(n.ok)return;b(r,n)}U(r);let u=Array.from(r).length,l=null;for(let n of[{clearPadding:12,minClear:8,maxClear:48,chunkSize:i>0?1:O,inputDelayMs:i},{clearPadding:24,minClear:16,maxClear:96,chunkSize:i>0?1:4,inputDelayMs:i>0?i:15}]){var c,s;await P(t,e,a),await K(t,"fill");let i=(c=u+n.clearPadding,s=n.minClear,Math.max(s,Math.min(n.maxClear,c)));await H(t,i),await L(t,{action:"fill",text:r,chunkSize:n.chunkSize,delayMs:n.inputDelayMs});let o=await p(t,e,a,r);if(l=o,o.ok)return;"ime_capture"===o.reason&&b(r,o)}b(r,l)}function b(t,e){let n;throw new u("COMMAND_FAILED",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",(n=function(t,e){var n;if(!e)return{expected:t,actual:null,failureReason:"text_mismatch",targetInput:null,actualInput:null};let a=!0===(n=e).masked||s(n.targetInput)||s(n.actualInput),r={failureReason:e.reason??"text_mismatch",targetInput:d(e.targetInput),actualInput:d(e.actualInput)};return a?{...r,expectedLength:Array.from(t).length,actual:null,masked:!0,actualLength:Array.from(e.actual??"").length}:{...r,expected:t,actual:e.actual}}(t,e),e?.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 D(t,n,a){let r=await R(t),i=l({direction:n,amount:a?.amount,pixels:a?.pixels,referenceWidth:r.width,referenceHeight:r.height}),o=a?.durationMs??300;return await e(t,["shell","input","swipe",String(i.x1),String(i.y1),String(i.x2),String(i.y2),String(o)]),{...i,...a?.durationMs!==void 0?{durationMs:a.durationMs}:{}}}async function K(e,n){let r;try{r=await a(e)}catch(e){t({level:"warn",phase:"android_input_ownership_probe_failed",data:{action:n,error:e instanceof Error?e.message:String(e)}});return}if("ime"===r.inputOwner)throw new u("COMMAND_FAILED","KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.",{failureReason:"ime_capture",action:n,inputOwner:r.inputOwner,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,nextAction:"Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry."})}async function R(t){let n=(await e(t,["shell","wm","size"])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new u("COMMAND_FAILED","Unable to read screen size");return{width:Number(n[1]),height:Number(n[2])}}let O=8;async function L(t,n){let a=n.text.split("\n");for(let[r,i]of a.entries()){let o=function(t,e){let n=Math.max(1,Math.floor(e)),a=[],r=Array.from(t);for(let t=0;t<r.length;t+=n)a.push(r.slice(t,t+n).join(""));return a.length>0?a:[""]}(i,n.chunkSize);for(let[e,i]of o.entries())await z(t,i),n.delayMs>0&&(e+1<o.length||r+1<a.length)&&await c(n.delayMs);r+1<a.length&&await e(t,["shell","input","keyevent","ENTER"])}F(n.action,"adb-shell",n.text)}async function z(t,n){if(n)try{await e(t,["shell","input","text",n.replace(/ /g,"%s")])}catch(t){if(function(t){if(!(t instanceof u)||"COMMAND_FAILED"!==t.code)return!1;let e=t.details?.stderr,n=("string"==typeof e?e:"").toLowerCase();return!!(n.includes("exception occurred while executing 'text'")||n.includes("nullpointerexception")&&n.includes("inputshellcommand.sendtext"))}(t))throw T(n,t);throw t}}function U(t){if(!function(t){for(let e of t){let t=e.codePointAt(0);if(void 0!==t&&"\n"!==e&&(t<32||t>126))return!1}return!0}(t))throw T(t)}function T(t,e){return new u("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(t).length,textPreview:t.slice(0,32)},e instanceof Error?e:void 0)}function F(e,n,a){t({phase:"android_text_injection",data:{action:e,backend:n,textLength:Array.from(a).length}})}async function H(t,n){let a=Math.max(0,n);await e(t,["shell","input","keyevent","KEYCODE_MOVE_END"],{allowFailure:!0});for(let n=0;n<a;n+=24){let r=Math.min(24,a-n);await e(t,["shell","input","keyevent",...Array(r).fill("KEYCODE_DEL")],{allowFailure:!0})}}export{v as appSwitcherAndroid,I as backAndroid,N as fillAndroid,P as focusAndroid,R as getAndroidScreenSize,M as homeAndroid,E as longPressAndroid,A as pressAndroid,k as pressAndroidEnter,h as readAndroidTextAtPoint,S as rotateAndroid,D as scrollAndroid,x as swipeAndroid,C as typeAndroid};
|
package/dist/src/interaction.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{__webpack_require__ as e}from"./rslib-runtime.js";import{createDaemonRuntimeSessionStore as t,setSessionSnapshot as r,dispatchCommand as a,requireCommandSupported as n,ensureAndroidBlockingSystemDialogReady as s,errorResponse as o,NO_ACTIVE_SESSION_MESSAGE as i,noActiveSessionError as l,recoverAndroidBlockingSystemDialog as c,getActiveAndroidSnapshotFreshness as f}from"./9722.js";import{buttonTag as u,resolveClickButton as d,readFillTargetFromPositionals as p,getClickButtonValidationError as g,successText as m}from"./2948.js";import{createAgentDevice as k}from"./7871.js";import{asAppError as y,normalizeError as w,AppError as h}from"./485.js";import{assertAndroidPressStayedInApp as b,isAndroidEscapeError as S,createDaemonRuntimePolicy as _,dispatchGetViaRuntime as x,dispatchIsViaRuntime as v,isDirectIosSelectorFallbackError as F,refSnapshotFlagGuardResponse as N,readSimpleIosSelectorTarget as M}from"./selector-runtime.js";import{resolveWebProvider as P}from"./provider.js";import{interaction_snapshot_captureSnapshotForSession as R,readSnapshotNodesReferenceFrame as C,resolveDirectTouchReferenceFrameSafely as q,buildTouchVisualizationResult as A,finalizeTouchInteraction as I}from"./8184.js";import{emitDiagnostic as H}from"./432.js";import{PUBLIC_COMMANDS as K}from"./1986.js";var E={};function D(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:o("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 O(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}function U(e,t){let r=O(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let a=e[0]??"";if(a.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:a,fallbackLabel:e.slice(1).join(" ").trim()}};let n=e.join(" ").trim();return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:o("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}function T(e){return"ref"===e.kind?{ref:L(e.target?.kind==="ref"?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain}:"selector"===e.kind?{selector:e.target?.kind==="selector"?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel}:{}}function L(e){return e?.startsWith("@")?e.slice(1):e}function j(e){let n=e.sessionStore.get(e.sessionName);if(!n)throw new h("SESSION_NOT_FOUND",i);return k({backend:function(e){let{req:t,session:r}=e,n=function(e){if("web"!==e.device.platform)return;let t=P();return t.clickRef||t.fillRef?t:void 0}(r);return{platform:r.device.platform,captureSnapshot:async(a,n)=>({snapshot:await e.captureSnapshotForSession(r,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:n?.interactiveOnly===!0,includeRects:n?.includeRects===!0})}),tap:async(n,s)=>B(await a(r.device,"press",[String(s.x),String(s.y)],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),tapTarget:n?.clickRef?async(e,t)=>(await n.clickRef?.(t.ref),{ref:L(t.ref)}):void 0,fill:async(n,s,o)=>B(await a(r.device,"fill",[String(s.x),String(s.y),o],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),fillTarget:n?.fillRef?async(e,t,r,a)=>(await n.fillRef?.(t.ref,r,a),{ref:L(t.ref),text:r,delayMs:a?.delayMs??0}):void 0,longPress:async(n,s,o)=>B(await a(r.device,"longpress",[String(s.x),String(s.y),...o?.durationMs===void 0?[]:[String(o.durationMs)]],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),typeText:async(n,s)=>B(await a(r.device,"type",[s],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath)))}}({...e,session:n}),..._("interaction commands",{plural:!0}),sessions:t({sessionName:e.sessionName,getSession:()=>n,recordOptions:{includeSnapshot:!0},setRecord:t=>{t.snapshot&&(r(n,t.snapshot),e.sessionStore.set(e.sessionName,n))}})})}function B(e){return e&&"object"==typeof e?e:void 0}async function G(e){switch(e.req.command){case"press":return await W(e,"press");case"click":return await W(e,"click");case"longpress":return await W(e,"longpress");case"fill":return await z(e);default:return null}}async function W(e,t){let r,{req:a,sessionName:s,sessionStore:i}=e,c=i.get(s);if(!c)return l();let f="click"===t?"click":t,p="longpress"===t?"longpress":"press",m=D(c,f);if(m)return m;let k=n(p,c.device);if(k)return k;let y=d(a.flags),w=u(y);if("longpress"!==t&&"primary"!==y){let e=g({commandLabel:f,platform:c.device.platform,button:y,count:a.flags?.count,intervalMs:a.flags?.intervalMs,holdMs:a.flags?.holdMs,jitterPx:a.flags?.jitterPx,doubleTap:a.flags?.doubleTap});if(e)return o(e.code,e.message,e.details)}let h="longpress"===t?function(e){var t,r,a;let n,s=O(e);if(s){return{ok:!0,target:{kind:"point",x:s.x,y:s.y},...void 0===(t=e[2])?{}:{durationMs:Number(t)}}}let o=(n=(r=e).at(-1),r.length>1&&void 0!==(a=n)&&""!==a.trim()&&Number.isFinite(Number(a))?{targetPositionals:r.slice(0,-1),duration:{durationMs:Number(n)}}:{targetPositionals:r,duration:{}}),i=U(o.targetPositionals,"longpress");return i.ok?{ok:!0,target:i.target,...o.duration}:i}(a.positionals??[]):U(a.positionals??[],f);if(!h.ok)return h.response;if("ref"===h.target.kind){let n=e.refSnapshotFlagGuardResponse("longpress"===t?"longpress":"press",a.flags);if(n)return n;r=await ee(e,c)}let S=function(e){var t;let{session:r,commandLabel:a,target:n,flags:s}=e;if("click"!==a||"selector"!==n.kind||(t=s,t?.count!==void 0||t?.intervalMs!==void 0||t?.holdMs!==void 0||t?.jitterPx!==void 0||t?.doubleTap!==void 0||t?.clickButton!==void 0&&"primary"!==t.clickButton))return null;let o=M({session:r,selectorExpression:n.selector});return o?{...o,...s?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:c,commandLabel:f,target:h.target,flags:a.flags});if(S){let t=await X(e,c,S);if(t)return t}let _="longpress"===t?h.durationMs:void 0;return await Q(e,{androidFreshnessBaseline:r,run:async e=>await V({runtime:e,command:t,target:h.target,sessionName:s,requestId:a.meta?.requestId,clickButton:y,flags:a.flags,durationMs:_}),afterRun:async e=>{if(!c.lease?.leaseProvider){var t;await b(c,(t=h.target,"point"===t.kind?"coordinate tap":"ref"===e.kind&&e.target?.kind==="ref"?e.target.ref:"selector"===e.kind&&e.target?.kind==="selector"?e.target.selector:"target"))}},buildPayloads:async r=>{var a;let n="durationMs"in(a=r)?a.durationMs:void 0,s=await $({params:e,session:c,result:r,extra:"longpress"===t?{...void 0!==n?{durationMs:n}:{},gesture:"longpress"}:w});return{result:s,responseData:s}}})}async function V(e){let{runtime:t,command:r,target:a,sessionName:n,requestId:s,flags:o}=e;if("longpress"===r)return await t.interactions.longPress(a,{session:n,requestId:s,durationMs:e.durationMs});let i={session:n,requestId:s,button:e.clickButton,count:o?.count,intervalMs:o?.intervalMs,holdMs:o?.holdMs,jitterPx:o?.jitterPx,doubleTap:o?.doubleTap};return"click"===r?await t.interactions.click(a,i):await t.interactions.press(a,i)}async function $(e){let{params:t,session:r,result:a,extra:n}=e,s="point"===a.kind?await q({session:r,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession}):C(r.snapshot?.nodes??[]);return A({data:a.backendResult,fallbackX:a.point?.x,fallbackY:a.point?.y,referenceFrame:s,extra:{...T(a),...n}})}async function X(e,t,r){return await Y({params:e,session:t,selector:r,command:"press",positionals:[],extra:{selector:r.raw},fallbackPhase:"ios_direct_selector_tap_fallback"})}async function Y(e){let{params:t,session:r,selector:n,command:s,positionals:o,extra:i,fallbackPhase:l}=e,c=Date.now();try{var f,u;let e,l,d=await a(r.device,s,o,t.req.flags?.out,{...t.contextFromFlags(t.req.flags,r.appBundleId,r.trace?.outPath),directElementSelector:n,surface:r.surface})??{},p=Date.now(),g=(f=d,e="number"==typeof f.x?f.x:void 0,l="number"==typeof f.y?f.y:void 0,void 0!==e&&void 0!==l?{x:e,y:l}:{x:0,y:0}),m=A({data:d,fallbackX:g.x,fallbackY:g.y,referenceFrame:(u=d,"number"==typeof u.referenceWidth&&"number"==typeof u.referenceHeight?{referenceWidth:u.referenceWidth,referenceHeight:u.referenceHeight}:void 0),extra:{...i,...function(e,t){if(!e.allowNonHittableCoordinateFallback)return{};let r="tapped via non-hittable coordinate fallback"===t.message;return{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:r,...r?{maestroFallbackReason:"non-hittable-coordinate"}:{}}}(n,d)}});return I({session:r,sessionStore:t.sessionStore,command:t.req.command,positionals:t.req.positionals??[],retryPositionals:et(g),flags:t.req.flags,result:m,responseData:m,actionStartedAt:c,actionFinishedAt:p})}catch(e){if(!F(e))return{ok:!1,error:w(e)};return H({level:"debug",phase:l,data:{selector:n.raw,error:e instanceof Error?e.message:String(e)}}),null}}async function z(e){let{req:t,sessionName:r,sessionStore:a}=e,s=a.get(r);if(s){let e=D(s,"fill");if(e)return e;let t=n("fill",s.device);if(t)return t}if(!s)return l();let i=function(e){let t=e[0]??"";if(t.startsWith("@")){var r;let a=p(e).text;return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:(r=e).length>=3&&r[1]?.trim()||""},text:a}:{ok:!1,response:o("INVALID_ARGS","fill requires text after ref")}}let a=O(e);if(a){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:a.x,y:a.y},text:t}:{ok:!1,response:o("INVALID_ARGS","fill requires text after coordinates")}}let n=p(e);return"selector"!==n.kind?{ok:!1,response:o("INVALID_ARGS","fill requires x y text, @ref text, or selector text")}:n.text.trim()?{ok:!0,target:{kind:"selector",selector:n.target.selector},text:n.text}:{ok:!1,response:o("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!i.ok)return i.response;if("ref"===i.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r;await ee(e,s)}let c=function(e){let{session:t,target:r,flags:a}=e;if("selector"!==r.kind)return null;let n=M({session:t,selectorExpression:r.selector});return n?{...n,...a?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:s,target:i.target,flags:t.flags});if(c){let t=await J(e,s,c,i.text);if(t)return t}return await Q(e,{run:async e=>await e.interactions.fill(i.target,i.text,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),buildPayloads:e=>{let t="point"===e.kind?void 0:C(s.snapshot?.nodes??[]),r=A({data:e.backendResult,fallbackX:e.point?.x,fallbackY:e.point?.y,referenceFrame:t,extra:{...T(e),text:i.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:L(e.target?.kind==="ref"?e.target.ref:void 0),...e.point?{x:e.point.x,y:e.point.y}:{}}}:r;return e.warning&&(a.warning=e.warning),{result:r,responseData:a}}})}async function J(e,t,r,a){return await Y({params:e,session:t,selector:r,command:"fill",positionals:[a],extra:{selector:r.raw,text:a},fallbackPhase:"ios_direct_selector_fill_fallback"})}async function Q(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return l();let a=j(e),n=Date.now();try{let{readiness:s,runtimeResult:o}=await Z(r,e.req.command,async()=>{let e=await t.run(a);return await t.afterRun?.(e),e}),i=Date.now(),{result:l,responseData:c}=await t.buildPayloads(o);return"recovered"===s.status&&(l.warning=s.warning,c.warning=s.warning),I({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],retryPositionals:function(e,t){if(("ref"!==t.kind||t.node)&&("click"===e||"press"===e)&&t.point)return et(t.point)}(e.req.command,o),flags:e.req.flags,result:l,responseData:c,actionStartedAt:n,actionFinishedAt:i,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(t){let e=y(t);if(S(e))throw e;return{ok:!1,error:w(t)}}}async function Z(e,t,r){if(e.lease?.leaseProvider)return{readiness:{status:"clear"},runtimeResult:await r()};let a=await s({session:e,command:t,phase:"before-command"}),n=await r();return await s({session:e,command:t,phase:"after-command"}),{readiness:a,runtimeResult:n}}async function ee(e,t){if(!f(t))return;let r=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){H({level:"warn",phase:"android_ref_snapshot_refresh_failed",data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return r}function et(e){return[String(e.x),String(e.y)]}async function er(e){let t=await G({...e,captureSnapshotForSession:R,refSnapshotFlagGuardResponse:N});if(t)return t;switch(e.req.command){case K.type:return await ea({...e,captureSnapshotForSession:R});case"get":return await x(e);case"is":return await v(e);default:return null}}async function ea(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return l();let s=n(K.type,a.device);if(s)return s;let o=await en(a);return o||await es(e,a)}async function en(e){return"android"===e.device.platform&&e.recording&&"failed"===(await c({session:e})).status?o("COMMAND_FAILED","Android system dialog blocked the recording session"):null}async function es(e,t){let{req:r,sessionName:a,sessionStore:n}=e,o=(r.positionals??[]).join(" "),i=j(e),l=Date.now();try{let e=await s({session:t,command:r.command,phase:"before-command"}),c=await i.interactions.typeText(o,{session:a,requestId:r.meta?.requestId,delayMs:r.flags?.delayMs});await s({session:t,command:r.command,phase:"after-command"});let f=Date.now(),u={...c.backendResult??{},text:c.text,delayMs:c.delayMs,...m(c.message??`Typed ${Array.from(c.text).length} chars`)};return"recovered"===e.status&&(u.warning=e.warning),I({session:t,sessionStore:n,command:r.command,positionals:r.positionals??[],flags:r.flags,result:u,responseData:u,actionStartedAt:l,actionFinishedAt:f})}catch(e){return{ok:!1,error:w(e)}}}e.r(E),e.d(E,{handleInteractionCommands:()=>er});export{E as interaction_namespaceObject};
|
|
1
|
+
import{__webpack_require__ as e}from"./rslib-runtime.js";import{isMacOs as t,publicPlatformString as r}from"./6849.js";import{createDaemonRuntimeSessionStore as a,setSessionSnapshot as n,dispatchCommand as s,requireCommandSupported as o,ensureAndroidBlockingSystemDialogReady as i,errorResponse as l,NO_ACTIVE_SESSION_MESSAGE as c,noActiveSessionError as f,recoverAndroidBlockingSystemDialog as u,getActiveAndroidSnapshotFreshness as d}from"./9722.js";import{buttonTag as p,resolveClickButton as g,readFillTargetFromPositionals as m,getClickButtonValidationError as k,successText as y}from"./2948.js";import{createAgentDevice as w}from"./7871.js";import{asAppError as _,normalizeError as S,AppError as h}from"./485.js";import{assertAndroidPressStayedInApp as b,isAndroidEscapeError as x,createDaemonRuntimePolicy as v,dispatchGetViaRuntime as F,dispatchIsViaRuntime as N,isDirectIosSelectorFallbackError as M,refSnapshotFlagGuardResponse as P,readSimpleIosSelectorTarget as R}from"./selector-runtime.js";import{resolveWebProvider as C}from"./provider.js";import{interaction_snapshot_captureSnapshotForSession as A,readSnapshotNodesReferenceFrame as q,resolveDirectTouchReferenceFrameSafely as I,buildTouchVisualizationResult as K,finalizeTouchInteraction as H}from"./8184.js";import{emitDiagnostic as E}from"./8875.js";import{PUBLIC_COMMANDS as D}from"./1986.js";var U={};function O(e,r){return t(e.device)&&("desktop"===e.surface||"menubar"===e.surface)&&("menubar"!==e.surface||"click"!==r&&"press"!==r)?l("UNSUPPORTED_OPERATION",`${r} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`):null}function T(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}function L(e,t){let r=T(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let a=e[0]??"";if(a.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:a,fallbackLabel:e.slice(1).join(" ").trim()}};let n=e.join(" ").trim();return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:l("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}function j(e){return"ref"===e.kind?{ref:B(e.target?.kind==="ref"?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain}:"selector"===e.kind?{selector:e.target?.kind==="selector"?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel}:{}}function B(e){return e?.startsWith("@")?e.slice(1):e}function G(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new h("SESSION_NOT_FOUND",c);return w({backend:function(e){let{req:t,session:a}=e,n=function(e){if("web"!==e.device.platform)return;let t=C();return t.clickRef||t.fillRef?t:void 0}(a);return{platform:r(a.device),captureSnapshot:async(r,n)=>({snapshot:await e.captureSnapshotForSession(a,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:n?.interactiveOnly===!0,includeRects:n?.includeRects===!0})}),tap:async(r,n)=>W(await s(a.device,"press",[String(n.x),String(n.y)],t.flags?.out,e.contextFromFlags(t.flags,a.appBundleId,a.trace?.outPath))),tapTarget:n?.clickRef?async(e,t)=>(await n.clickRef?.(t.ref),{ref:B(t.ref)}):void 0,fill:async(r,n,o)=>W(await s(a.device,"fill",[String(n.x),String(n.y),o],t.flags?.out,e.contextFromFlags(t.flags,a.appBundleId,a.trace?.outPath))),fillTarget:n?.fillRef?async(e,t,r,a)=>(await n.fillRef?.(t.ref,r,a),{ref:B(t.ref),text:r,delayMs:a?.delayMs??0}):void 0,longPress:async(r,n,o)=>W(await s(a.device,"longpress",[String(n.x),String(n.y),...o?.durationMs===void 0?[]:[String(o.durationMs)]],t.flags?.out,e.contextFromFlags(t.flags,a.appBundleId,a.trace?.outPath))),typeText:async(r,n)=>W(await s(a.device,"type",[n],t.flags?.out,e.contextFromFlags(t.flags,a.appBundleId,a.trace?.outPath)))}}({...e,session:t}),...v("interaction commands",{plural:!0}),sessions:a({sessionName:e.sessionName,getSession:()=>t,recordOptions:{includeSnapshot:!0},setRecord:r=>{r.snapshot&&(n(t,r.snapshot),e.sessionStore.set(e.sessionName,t))}})})}function W(e){return e&&"object"==typeof e?e:void 0}async function V(e){switch(e.req.command){case"press":return await $(e,"press");case"click":return await $(e,"click");case"longpress":return await $(e,"longpress");case"fill":return await Q(e);default:return null}}async function $(e,t){let a,{req:n,sessionName:s,sessionStore:i}=e,c=i.get(s);if(!c)return f();let u="click"===t?"click":t,d="longpress"===t?"longpress":"press",m=O(c,u);if(m)return m;let y=o(d,c.device);if(y)return y;let w=g(n.flags),_=p(w);if("longpress"!==t&&"primary"!==w){let e=k({commandLabel:u,platform:r(c.device),button:w,count:n.flags?.count,intervalMs:n.flags?.intervalMs,holdMs:n.flags?.holdMs,jitterPx:n.flags?.jitterPx,doubleTap:n.flags?.doubleTap});if(e)return l(e.code,e.message,e.details)}let S="longpress"===t?function(e){var t,r,a;let n,s=T(e);if(s){return{ok:!0,target:{kind:"point",x:s.x,y:s.y},...void 0===(t=e[2])?{}:{durationMs:Number(t)}}}let o=(n=(r=e).at(-1),r.length>1&&void 0!==(a=n)&&""!==a.trim()&&Number.isFinite(Number(a))?{targetPositionals:r.slice(0,-1),duration:{durationMs:Number(n)}}:{targetPositionals:r,duration:{}}),i=L(o.targetPositionals,"longpress");return i.ok?{ok:!0,target:i.target,...o.duration}:i}(n.positionals??[]):L(n.positionals??[],u);if(!S.ok)return S.response;if("ref"===S.target.kind){let r=e.refSnapshotFlagGuardResponse("longpress"===t?"longpress":"press",n.flags);if(r)return r;a=await er(e,c)}let h=function(e){var t;let{session:r,commandLabel:a,target:n,flags:s}=e;if("click"!==a||"selector"!==n.kind||(t=s,t?.count!==void 0||t?.intervalMs!==void 0||t?.holdMs!==void 0||t?.jitterPx!==void 0||t?.doubleTap!==void 0||t?.clickButton!==void 0&&"primary"!==t.clickButton))return null;let o=R({session:r,selectorExpression:n.selector});return o?{...o,...s?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:c,commandLabel:u,target:S.target,flags:n.flags});if(h){let t=await z(e,c,h);if(t)return t}let x="longpress"===t?S.durationMs:void 0;return await ee(e,{androidFreshnessBaseline:a,run:async e=>await X({runtime:e,command:t,target:S.target,sessionName:s,requestId:n.meta?.requestId,clickButton:w,flags:n.flags,durationMs:x}),afterRun:async e=>{if(!c.lease?.leaseProvider){var t;await b(c,(t=S.target,"point"===t.kind?"coordinate tap":"ref"===e.kind&&e.target?.kind==="ref"?e.target.ref:"selector"===e.kind&&e.target?.kind==="selector"?e.target.selector:"target"))}},buildPayloads:async r=>{var a;let n="durationMs"in(a=r)?a.durationMs:void 0,s=await Y({params:e,session:c,result:r,extra:"longpress"===t?{...void 0!==n?{durationMs:n}:{},gesture:"longpress"}:_});return{result:s,responseData:s}}})}async function X(e){let{runtime:t,command:r,target:a,sessionName:n,requestId:s,flags:o}=e;if("longpress"===r)return await t.interactions.longPress(a,{session:n,requestId:s,durationMs:e.durationMs});let i={session:n,requestId:s,button:e.clickButton,count:o?.count,intervalMs:o?.intervalMs,holdMs:o?.holdMs,jitterPx:o?.jitterPx,doubleTap:o?.doubleTap};return"click"===r?await t.interactions.click(a,i):await t.interactions.press(a,i)}async function Y(e){let{params:t,session:r,result:a,extra:n}=e,s="point"===a.kind?await I({session:r,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession}):q(r.snapshot?.nodes??[]);return K({data:a.backendResult,fallbackX:a.point?.x,fallbackY:a.point?.y,referenceFrame:s,extra:{...j(a),...n}})}async function z(e,t,r){return await J({params:e,session:t,selector:r,command:"press",positionals:[],extra:{selector:r.raw},fallbackPhase:"ios_direct_selector_tap_fallback"})}async function J(e){let{params:t,session:r,selector:a,command:n,positionals:o,extra:i,fallbackPhase:l}=e,c=Date.now();try{var f,u;let e,l,d=await s(r.device,n,o,t.req.flags?.out,{...t.contextFromFlags(t.req.flags,r.appBundleId,r.trace?.outPath),directElementSelector:a,surface:r.surface})??{},p=Date.now(),g=(f=d,e="number"==typeof f.x?f.x:void 0,l="number"==typeof f.y?f.y:void 0,void 0!==e&&void 0!==l?{x:e,y:l}:{x:0,y:0}),m=K({data:d,fallbackX:g.x,fallbackY:g.y,referenceFrame:(u=d,"number"==typeof u.referenceWidth&&"number"==typeof u.referenceHeight?{referenceWidth:u.referenceWidth,referenceHeight:u.referenceHeight}:void 0),extra:{...i,...function(e,t){if(!e.allowNonHittableCoordinateFallback)return{};let r="tapped via non-hittable coordinate fallback"===t.message;return{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:r,...r?{maestroFallbackReason:"non-hittable-coordinate"}:{}}}(a,d)}});return H({session:r,sessionStore:t.sessionStore,command:t.req.command,positionals:t.req.positionals??[],retryPositionals:ea(g),flags:t.req.flags,result:m,responseData:m,actionStartedAt:c,actionFinishedAt:p})}catch(e){if(!M(e))return{ok:!1,error:S(e)};return E({level:"debug",phase:l,data:{selector:a.raw,error:e instanceof Error?e.message:String(e)}}),null}}async function Q(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(n){let e=O(n,"fill");if(e)return e;let t=o("fill",n.device);if(t)return t}if(!n)return f();let s=function(e){let t=e[0]??"";if(t.startsWith("@")){var r;let a=m(e).text;return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:(r=e).length>=3&&r[1]?.trim()||""},text:a}:{ok:!1,response:l("INVALID_ARGS","fill requires text after ref")}}let a=T(e);if(a){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:a.x,y:a.y},text:t}:{ok:!1,response:l("INVALID_ARGS","fill requires text after coordinates")}}let n=m(e);return"selector"!==n.kind?{ok:!1,response:l("INVALID_ARGS","fill requires x y text, @ref text, or selector text")}:n.text.trim()?{ok:!0,target:{kind:"selector",selector:n.target.selector},text:n.text}:{ok:!1,response:l("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!s.ok)return s.response;if("ref"===s.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r;await er(e,n)}let i=function(e){let{session:t,target:r,flags:a}=e;if("selector"!==r.kind)return null;let n=R({session:t,selectorExpression:r.selector});return n?{...n,...a?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:n,target:s.target,flags:t.flags});if(i){let t=await Z(e,n,i,s.text);if(t)return t}return await ee(e,{run:async e=>await e.interactions.fill(s.target,s.text,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),buildPayloads:e=>{let t="point"===e.kind?void 0:q(n.snapshot?.nodes??[]),r=K({data:e.backendResult,fallbackX:e.point?.x,fallbackY:e.point?.y,referenceFrame:t,extra:{...j(e),text:s.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:B(e.target?.kind==="ref"?e.target.ref:void 0),...e.point?{x:e.point.x,y:e.point.y}:{}}}:r;return e.warning&&(a.warning=e.warning),{result:r,responseData:a}}})}async function Z(e,t,r,a){return await J({params:e,session:t,selector:r,command:"fill",positionals:[a],extra:{selector:r.raw,text:a},fallbackPhase:"ios_direct_selector_fill_fallback"})}async function ee(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return f();let a=G(e),n=Date.now();try{let{readiness:s,runtimeResult:o}=await et(r,e.req.command,async()=>{let e=await t.run(a);return await t.afterRun?.(e),e}),i=Date.now(),{result:l,responseData:c}=await t.buildPayloads(o);return"recovered"===s.status&&(l.warning=s.warning,c.warning=s.warning),H({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],retryPositionals:function(e,t){if(("ref"!==t.kind||t.node)&&("click"===e||"press"===e)&&t.point)return ea(t.point)}(e.req.command,o),flags:e.req.flags,result:l,responseData:c,actionStartedAt:n,actionFinishedAt:i,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(t){let e=_(t);if(x(e))throw e;return{ok:!1,error:S(t)}}}async function et(e,t,r){if(e.lease?.leaseProvider)return{readiness:{status:"clear"},runtimeResult:await r()};let a=await i({session:e,command:t,phase:"before-command"}),n=await r();return await i({session:e,command:t,phase:"after-command"}),{readiness:a,runtimeResult:n}}async function er(e,t){if(!d(t))return;let r=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){E({level:"warn",phase:"android_ref_snapshot_refresh_failed",data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return r}function ea(e){return[String(e.x),String(e.y)]}async function en(e){let t=await V({...e,captureSnapshotForSession:A,refSnapshotFlagGuardResponse:P});if(t)return t;switch(e.req.command){case D.type:return await es({...e,captureSnapshotForSession:A});case"get":return await F(e);case"is":return await N(e);default:return null}}async function es(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return f();let n=o(D.type,a.device);if(n)return n;let s=await eo(a);return s||await ei(e,a)}async function eo(e){return"android"===e.device.platform&&e.recording&&"failed"===(await u({session:e})).status?l("COMMAND_FAILED","Android system dialog blocked the recording session"):null}async function ei(e,t){let{req:r,sessionName:a,sessionStore:n}=e,s=(r.positionals??[]).join(" "),o=G(e),l=Date.now();try{let e=await i({session:t,command:r.command,phase:"before-command"}),c=await o.interactions.typeText(s,{session:a,requestId:r.meta?.requestId,delayMs:r.flags?.delayMs});await i({session:t,command:r.command,phase:"after-command"});let f=Date.now(),u={...c.backendResult??{},text:c.text,delayMs:c.delayMs,...y(c.message??`Typed ${Array.from(c.text).length} chars`)};return"recovered"===e.status&&(u.warning=e.warning),H({session:t,sessionStore:n,command:r.command,positionals:r.positionals??[],flags:r.flags,result:u,responseData:u,actionStartedAt:l,actionFinishedAt:f})}catch(e){return{ok:!1,error:S(e)}}}e.r(U),e.d(U,{handleInteractionCommands:()=>en});export{U as interaction_namespaceObject};
|
package/dist/src/interactor.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readSnapshotQualityVerdict as
|
|
1
|
+
import{readSnapshotQualityVerdict as e,normalizeScrollDurationMs as a,buildScrollGesturePlan as t,assertScrollGestureInput as n}from"./2948.js";import{isIosFamily as o,isTvOsDevice as d,isMacOs as i}from"./6849.js";import{runMacOsScreenshotAction as r,runAppleRunnerCommand as s}from"./9722.js";import{parseRunnerSequenceResult as u,buildRunnerSequenceCommand as l}from"./runner-sequence.js";import{writeIosClipboardText as p,openIosApp as c,openIosDevice as m,screenshotIos as y,closeIosApp as v,setIosSetting as h,readIosClipboardText as f}from"./apps.js";import{withDiagnosticTimer as I}from"./8875.js";import{AppError as w}from"./485.js";function B(e,a,t){return{command:"remotePress",remoteButton:e,...void 0!==t?{durationMs:t}:{},...void 0!==a?{appBundleId:a}:{}}}function M(e,a,n,o={includeDuration:!0}){let d=g(e.referenceWidth),i=g(e.referenceHeight);if(void 0===d||void 0===i)return C(e,{amount:n?.amount});let r=t({direction:a,amount:n?.amount,pixels:n?.pixels,referenceWidth:d,referenceHeight:i});return C(e,{amount:n?.amount,pixels:r.pixels,durationMs:o?.includeDuration?n?.durationMs:void 0,preferProvidedPixels:!0})}function _(e,a={includeDuration:!0}){return{...e?.amount!==void 0?{amount:e.amount}:{},...e?.pixels!==void 0?{pixels:e.pixels}:{},...a?.includeDuration&&e?.durationMs!==void 0?{durationMs:e.durationMs}:{}}}function g(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function C(e,a){var t,n,o,d;let i,r,s,u,{x1:l,y1:p,x2:c,y2:m}=(i=g((t=e).x),r=g(t.y),s=g(t.x2),u=g(t.y2),{...void 0!==i?{x1:i}:{},...void 0!==r?{y1:r}:{},...void 0!==s?{x2:s}:{},...void 0!==u?{y2:u}:{}}),y=g(e.referenceWidth),v=g(e.referenceHeight),h=(n=a,o=void 0!==l&&void 0!==c?Math.round(Math.abs(c-l)):void 0,d=void 0!==p&&void 0!==m?Math.round(Math.abs(m-p)):void 0,n?.preferProvidedPixels&&void 0!==n.pixels?n.pixels:void 0!==o&&o>0?o:void 0!==d&&d>0?d:void 0);return{...void 0!==l?{x1:l}:{},...void 0!==p?{y1:p}:{},...void 0!==c?{x2:c}:{},...void 0!==m?{y2:m}:{},...void 0!==y?{referenceWidth:y}:{},...void 0!==v?{referenceHeight:v}:{},...a?.amount!==void 0?{amount:a.amount}:{},...void 0!==h?{pixels:h}:{},...a?.durationMs!==void 0?{durationMs:a.durationMs}:{}}}async function S(e,a,t,n,o,d){return M(await e(a,{command:"desktopScroll",direction:o,..._(d,{includeDuration:!0}),appBundleId:t.appBundleId},n),o,d,{includeDuration:!0})}function x(e,a,t,n){return{command:"tap",x:t,y:n,...b(e)?{synthesized:!0}:{},appBundleId:a.appBundleId}}function b(e){return o(e)&&!d(e)}function D(e,a,t,n,i,r,s,u){var l,p;let c=o(e)&&!d(e)?(l=s,p=u.defaultDurationMs,void 0===l?p:Math.min(1e4,Math.max(16,Math.round(l)))):s??u.legacyDefaultDurationMs;return{command:"drag",x:t,y:n,x2:i,y2:r,...void 0!==c?{durationMs:c}:{},...!0===u.synthesized?{synthesized:!0}:{},appBundleId:a.appBundleId}}async function P(e,t,o,r,s,u){return(a(u?.durationMs,{invalidMessage:"scroll durationMs must be a non-negative integer at most 10000"}),d(t))?C(await e(t,B(s,o.appBundleId,u?.durationMs),r),{amount:u?.amount,durationMs:u?.durationMs}):(n(u??{}),i(t))?await S(e,t,o,r,s,u):M(await e(t,{command:"scroll",direction:s,..._(u),appBundleId:o.appBundleId},r),s,u)}function k(a,t){let n;if("watchos"===a.appleOs)throw new w("UNSUPPORTED_PLATFORM","watchOS is not supported: XCUITest cannot drive watchOS UI, so this device has no runner backend.");let{overrides:o,runnerOpts:M}={runnerOpts: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},overrides:{tap:async(e,o)=>await s(a,x(a,t,e,o),n),tapElementSelector:async e=>await s(a,{command:"tap",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,appBundleId:t.appBundleId},n),doubleTap:async(e,o)=>{let d=await s(a,l([{kind:"doubleTap",x:e,y:o}],t.appBundleId),n);return u(d),d},swipe:async(e,o,d,i,r)=>await s(a,D(a,t,e,o,d,i,r,{defaultDurationMs:250,synthesized:b(a)}),n),pan:async(e,o,d,i,r)=>await s(a,D(a,t,e,o,d,i,r,{defaultDurationMs:500,legacyDefaultDurationMs:500,synthesized:b(a)}),n),fling:async(e,o,d,i,r)=>await s(a,D(a,t,e,o,d,i,r,{defaultDurationMs:16,legacyDefaultDurationMs:16,synthesized:b(a)}),n),longPress:async(e,o,d)=>await s(a,{command:"longPress",x:e,y:o,durationMs:d,appBundleId:t.appBundleId},n),focus:async(e,o)=>await s(a,x(a,t,e,o),n),type:async(e,o)=>{await s(a,{command:"type",text:e,delayMs:o,textEntryMode:"\n"===e?void 0:"append",appBundleId:t.appBundleId},n)},fillElementSelector:async(e,o,d)=>await s(a,{command:"type",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,text:o,delayMs:d,textEntryMode:"replace",appBundleId:t.appBundleId},n),fill:async(e,o,d,i)=>await s(a,{command:"type",x:e,y:o,text:d,delayMs:i,textEntryMode:"replace",appBundleId:t.appBundleId},n),scroll:async(e,o)=>await P(s,a,t,n,e,o),pinch:async(e,o,d)=>{await s(a,{command:"pinch",scale:e,x:o,y:d,appBundleId:t.appBundleId},n)},rotateGesture:async(e,o,d,i)=>{await s(a,{command:"rotateGesture",degrees:e,x:o,y:d,velocity:i,appBundleId:t.appBundleId},n)},transformGesture:async e=>await s(a,{command:"transformGesture",x:e.x,y:e.y,dx:e.dx,dy:e.dy,scale:e.scale,degrees:e.degrees,durationMs:e.durationMs,appBundleId:t.appBundleId},n)}};return{open:(e,t)=>c(a,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,terminateRunningApp:t?.terminateRunningApp,url:t?.url}),openDevice:()=>m(a),close:e=>v(a,e),screenshot:async(e,t)=>{i(a)&&t?.surface&&"app"!==t.surface?await r(e,{surface:t.surface,fullscreen:t.fullscreen}):await y(a,e,{appBundleId:t?.appBundleId,fullscreen:t?.fullscreen,runnerOptions:M,normalizeStatusBar:t?.normalizeStatusBar,skipIosSimulatorBootCheck:t?.skipIosSimulatorBootCheck})},snapshot:async t=>{var n;let o={nodes:Array.isArray((n=await I("snapshot_capture",async()=>await s(a,{command:"snapshot",appBundleId:t?.appBundleId,interactiveOnly:t?.interactiveOnly,depth:t?.depth,scope:t?.scope,raw:t?.raw},M),{backend:"xctest"})).nodes)?n.nodes:void 0,truncated:"boolean"==typeof n.truncated?n.truncated:void 0,quality:e(n.snapshotQuality),message:"string"==typeof n.message&&n.message.trim().length>0?n.message:void 0},d=o.nodes??[];if(0===d.length&&"simulator"===a.kind)throw new w("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:d,truncated:o.truncated??!1,backend:"xctest",...o.quality?{quality:o.quality}:{},...!o.quality&&o.message?{warnings:[o.message]}:{}}},back:async e=>{d(a)?await s(a,B("menu",t.appBundleId),M):await s(a,{command:"system"===e?"backSystem":"backInApp",appBundleId:t.appBundleId},M)},home:async()=>{d(a)?await s(a,B("home",t.appBundleId),M):await s(a,{command:"home",appBundleId:t.appBundleId},M)},rotate:async e=>{await s(a,{command:"rotate",orientation:e,appBundleId:t.appBundleId},M)},appSwitcher:async()=>{await s(a,{command:"appSwitcher",appBundleId:t.appBundleId},M)},readClipboard:()=>f(a),writeClipboard:e=>p(a,e),setSetting:(e,t,n,o)=>h(a,e,t,n,o),...o}}export{k as createAppleInteractor};
|
package/dist/src/internal/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var e,t,r,s;let n,o=process.argv.slice(2);function c(e){return"--help"===e||"-h"===e}function i(e){import("../cli.js").then(({runCli:t})=>t(e)).catch(p)}function p(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}
|
|
2
|
-
`),process.exit(1)}1===(t=e=o).length&&("--version"===(r=t[0])||"-V"===r)&&(process.stdout.write(`0.18.
|
|
2
|
+
`),process.exit(1)}1===(t=e=o).length&&("--version"===(r=t[0])||"-V"===r)&&(process.stdout.write(`0.18.3
|
|
3
3
|
`),1)||0===e.length&&(import("../cli-help.js").then(({buildUsageText:e})=>{process.stdout.write(`${e()}
|
|
4
4
|
`),process.exit(1)}).catch(p),1)||void 0!==(n=function(e){var t,r,s,n;switch(e.length){case 1:return"help"===(t=e[0])||c(t)?null:void 0;case 2:return r=e[0],s=e[1],"help"===r?s:(n=r,c(s)?n:void 0);default:return}}(s=e))&&(import("../cli-help.js").then(({buildCommandUsageText:e,buildUsageText:t})=>{var r;if(null===n)return void process.stdout.write(`${t()}
|
|
5
5
|
`);let o=e("long-press"===(r=n)?"longpress":"metrics"===r?"perf":r);o?process.stdout.write(o):i(s)}).catch(p),1)||("mcp"!==o[0]||o.includes("--help")||o.includes("-h")?i(o):import("../server.js").then(({runAgentDeviceMcpServer:e})=>e()).catch(p));export{};
|
package/dist/src/lease.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PUBLIC_COMMANDS as e}from"./1986.js";import{
|
|
1
|
+
import{PUBLIC_COMMANDS as e}from"./1986.js";import{listDownloadableArtifacts as a,resolveRequestOrSessionLeaseScope as r,resolveLeaseScope as t}from"./9722.js";import{isProxyLeaseScope as o,leaseScopeToReleaseRequest as s,leaseScopeToAllocateRequest as i,leaseScopeToHeartbeatRequest as l}from"./2948.js";import{AppError as n}from"./485.js";async function d(a){let{req:o,sessionName:n,sessionStore:d,leaseRegistry:_,leaseLifecycleProvider:u,cloudArtifactProvider:v}=a,f=t(o);switch(o.command){case e.artifacts:{let e=r(o,d.get(n));return{ok:!0,data:await c(o,e,v)}}case"lease_allocate":{let e,a=_.allocateLease(i(f));try{e=await u?.allocate?.(a,{req:o})}catch(e){throw _.releaseLease(s({leaseId:a.leaseId,tenantId:a.tenantId,runId:a.runId,leaseBackend:a.backend,leaseProvider:a.leaseProvider,deviceKey:a.deviceKey,clientId:a.clientId})),e}return{ok:!0,data:{lease:a,...e?{provider:e}:{}}}}case"lease_heartbeat":{let e=_.heartbeatLease(l(f)),a=await u?.heartbeat?.(e,{req:o});return{ok:!0,data:{lease:e,...a?{provider:a}:{}}}}case"lease_release":{let e=_.releaseLease(s(f)),a=e.lease?await u?.release?.(e.lease,{req:o}):void 0;return{ok:!0,data:{released:e.released,...a?{provider:a}:{}}}}default:return null}}async function c(e,a,r){var t,s,i;let l,n=(t=e.flags,"string"==typeof(l=t?.providerSessionId)&&l.length>0?l:void 0);return(s=a,i=n,!o(s)&&(s.leaseProvider||i))?await u(a,n,r):await _(a.tenantId)}async function _(e){let r=await a(e);return{source:"daemon",status:"ready",artifacts:r,...0===r.length?{message:"No daemon artifacts available."}:{}}}async function u(e,a,r){if(!e.leaseProvider)throw new n("INVALID_ARGS","artifacts requires --provider for provider session lookup or an active cloud connection.");if(!e.leaseId&&!a)throw new n("INVALID_ARGS","artifacts requires an active cloud lease or --provider-session <id>.");let t=await r?.listCloudArtifacts?.({provider:e.leaseProvider,leaseId:e.leaseId,providerSessionId:a});if(!t)throw new n("UNSUPPORTED_OPERATION",`Cloud artifacts are not available for provider "${e.leaseProvider}".`);return t}export{d as handleLeaseCommands};
|
package/dist/src/linux.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{longPressLinux as t,pressLinux as e,typeLinux as n,scrollLinux as o,sendKey as r,fillLinux as a,focusLinux as i,swipeLinux as s,doubleClickLinux as p}from"./input-actions~1.js";import{snapshotLinux as u,resolveLinuxToolProvider as c}from"./9722.js";import{AppError as w}from"./485.js";import{withDiagnosticTimer as _}from"./
|
|
1
|
+
import{longPressLinux as t,pressLinux as e,typeLinux as n,scrollLinux as o,sendKey as r,fillLinux as a,focusLinux as i,swipeLinux as s,doubleClickLinux as p}from"./input-actions~1.js";import{snapshotLinux as u,resolveLinuxToolProvider as c}from"./9722.js";import{AppError as w}from"./485.js";import{withDiagnosticTimer as _}from"./8875.js";async function P(t){await c().desktop.openTarget(t)}async function d(t){await c().desktop.closeApp(t)}async function O(){await r("alt+Left",["56:1","105:1","105:0","56:0"])}async function f(){await r("super+d",["125:1","32:1","32:0","125:0"])}async function l(){return await c().clipboard.readText()}async function S(t){await c().clipboard.writeText(t)}async function E(t,e){await c().screenshot.capture(t,e)}function N(){return{open:t=>P(t),openDevice:()=>Promise.resolve(),close:t=>d(t),tap:(t,n)=>e(t,n),doubleTap:(t,e)=>p(t,e),swipe:(t,e,n,o,r)=>s(t,e,n,o,r),pan:(t,e,n,o,r)=>s(t,e,n,o,r),fling:()=>{throw new w("UNSUPPORTED_OPERATION","gesture fling not supported on Linux")},longPress:(e,n,o)=>t(e,n,o),focus:(t,e)=>i(t,e),type:(t,e)=>n(t,e),fill:(t,e,n,o)=>a(t,e,n,o),scroll:(t,e)=>o(t,e),pinch:()=>{throw new w("UNSUPPORTED_OPERATION","gesture pinch not supported on Linux")},screenshot:(t,e)=>E(t,e),snapshot:async t=>{let e=await _("snapshot_capture",async()=>await u(t?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}},back:()=>O(),home:()=>f(),rotate:()=>{throw new w("UNSUPPORTED_OPERATION","rotate not supported on Linux")},rotateGesture:()=>{throw new w("UNSUPPORTED_OPERATION","gesture rotate not supported on Linux")},transformGesture:()=>{throw new w("UNSUPPORTED_OPERATION","gesture transform not supported on Linux")},appSwitcher:()=>{throw new w("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>l(),writeClipboard:t=>S(t),setSetting:()=>{throw new w("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}}}export{N as createLinuxInteractor};
|