agent-device 0.20.3 → 0.20.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.3.apk → agent-device-android-ime-helper-0.20.4.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.4.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.3.manifest.json → agent-device-android-ime-helper-0.20.4.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.4.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.4.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.3.manifest.json → agent-device-android-snapshot-helper-0.20.4.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +57 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +45 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +73 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +1 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +3 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +8 -2
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android-adb.d.ts +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-inventory.d.ts +4 -0
- package/dist/src/app-lifecycle.js +7 -7
- package/dist/src/app-resolution.js +1 -1
- package/dist/src/apps.js +5 -5
- package/dist/src/boot-diagnostics.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +27 -19
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +15 -14
- package/dist/src/client-metro.js +1 -1
- package/dist/src/{tv-remote.d.ts → cloud-artifacts.d.ts} +109 -126
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-surface.js +1 -1
- package/dist/src/context.js +1 -1
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/debug-symbols.js +4 -4
- package/dist/src/device-input-state.d.ts +2 -2
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/device.js +1 -9
- package/dist/src/devices2.js +1 -1
- package/dist/src/entities.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.d.ts +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/ime-lifecycle.js +9 -0
- package/dist/src/index.d.ts +592 -555
- package/dist/src/input-actions.js +4 -4
- package/dist/src/install-artifact.js +4 -4
- package/dist/src/install-artifact2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction.d.ts +7 -4
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -2
- package/dist/src/interactor2.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +14 -14
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +103 -198
- package/dist/src/limrun.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/logcat.js +1 -1
- package/dist/src/manifest.js +1 -1
- package/dist/src/metro.d.ts +1 -1
- package/dist/src/parser.js +2 -0
- package/dist/src/path-resolution.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/plist-xml.js +1 -0
- package/dist/src/plist.js +1 -1
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/process-lock.js +1 -1
- package/dist/src/provider-limrun-runtime.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +22 -22
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/reporting.js +7 -7
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-lease.js +1 -1
- package/dist/src/runner-provider.js +1 -1
- package/dist/src/runner-sequence.js +1 -1
- package/dist/src/runtime-transport.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/screenshot-geometry.js +1 -0
- package/dist/src/screenshot-result.js +6 -0
- package/dist/src/sdk-android-adb.d.ts +5 -6
- package/dist/src/sdk-android-adb.js +3 -3
- package/dist/src/sdk-batch-runner.d.ts +2 -2
- package/dist/src/sdk-batch-runner.js +3 -3
- package/dist/src/sdk-contracts.d.ts +21 -25
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +19 -4
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selector-vocabulary.js +1 -1
- package/dist/src/selectors.d.ts +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +8 -8
- package/dist/src/setting-state.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot.js +1 -1
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/src.js +1 -0
- package/dist/src/tool-provider.js +3 -3
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tool-provider3.js +1 -1
- package/dist/src/update-check.js +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/viewport-dimension.js +14 -0
- package/package.json +17 -7
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.3.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.3.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.3.apk.sha256 +0 -1
- package/dist/src/android-input-method-overlays.js +0 -1
- package/dist/src/android-input-ownership.js +0 -1
- package/dist/src/apple-multitouch-support.js +0 -1
- package/dist/src/click-button.d.ts +0 -5
- package/dist/src/compatibility-policy.js +0 -1
- package/dist/src/gesture-plan-types.js +0 -1
- package/dist/src/gesture-plan.js +0 -1
- package/dist/src/launch-console.js +0 -1
- package/dist/src/recording-export-quality.js +0 -14
- package/dist/src/rolldown-runtime.js +0 -1
- package/dist/src/runtime2.js +0 -1
- package/dist/src/sdk-app-inventory.d.ts +0 -4
- package/dist/src/sdk-app-inventory.js +0 -1
- package/dist/src/snapshot-diagnostics.js +0 -6
- package/dist/src/xml.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{a as e,i as t,n,r,t as i}from"../png-worker-contract.js";import{S as a}from"../sdk-contracts.js";import{parentPort as o}from"node:worker_threads";function s(a){switch(a.kind){case`decode`:{let e=t(i(a.png),a.label);return{kind:`decode`,width:e.width,height:e.height,data:e.data}}case`encode`:{let t=new e.PNG({width:a.width,height:a.height});return t.data=i(a.data),{kind:`encode`,png:e.PNG.sync.write(t)}}case`rgb-difference`:return{kind:`rgb-difference`,...n(t(i(a.firstPng),a.label),t(i(a.secondPng),a.label))};case`diff-pixels`:return{kind:`diff-pixels`,...r(a)}}}function c(e){return e.buffer instanceof ArrayBuffer&&e.byteOffset===0&&e.byteLength===e.buffer.byteLength}function l(e){return u(e).filter(c).map(e=>e.buffer)}function u(e){switch(e.kind){case`decode`:return[e.data];case`encode`:return[e.png];case`rgb-difference`:return[];case`diff-pixels`:return[e.diffData,e.diffMask]}}const d=o;d&&d.on(`message`,e=>{let t;try{t={id:e.id,ok:!0,result:s(e)}}catch(n){t={id:e.id,ok:!1,error:a(n)}}d.postMessage(t,t.ok?l(t.result):[])});export{l as resultTransferList};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{ln as e}from"./viewport-dimension.js";import{it as t}from"./sdk-batch-runner.js";function n(t){return e(t)}function r(e,r){let i=n(e),a=i.leaseId??r?.leaseId,o=i.tenantId??r?.tenantId,s=i.runId??r?.runId;if(!(!o||!s||!a))return t({tenantId:o,runId:s,leaseId:a,leaseBackend:i.leaseBackend??r?.backend,leaseProvider:i.leaseProvider??r?.leaseProvider,deviceKey:i.deviceKey??r?.deviceKey,clientId:i.clientId??r?.clientId,expiresAt:r?.expiresAt})}function i(e,r){let i=n(e),a=r?.lease??r?.deviceLease??void 0;return t({tenantId:i.tenantId??a?.tenantId,runId:i.runId??a?.runId,leaseId:i.leaseId??a?.leaseId,leaseTtlMs:i.leaseTtlMs,leaseBackend:i.leaseBackend??a?.leaseBackend,leaseProvider:i.leaseProvider??a?.leaseProvider,deviceKey:i.deviceKey??a?.deviceKey,clientId:i.clientId??a?.clientId})}function a(e){let n=e.meta,r=t({leaseId:o(n?.leaseId),clientId:o(n?.clientId),tenantId:o(n?.tenantId),runId:o(n?.runId),leaseProvider:o(n?.leaseProvider),deviceKey:o(n?.deviceKey)});return Object.keys(r).length>0?r:void 0}function o(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}export{a as i,n,i as r,r as t};
|
package/dist/src/lease.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{Ht as t,hn as n,pn as r,sn as i,un as a}from"./viewport-dimension.js";import{n as o,r as s}from"./lease-context.js";import{_n as c}from"./internal/daemon.js";async function l(e){let{req:i,sessionName:c,sessionStore:l,leaseRegistry:p,providerRuntimeIds:m,providerRuntimeRequiredIds:h,leaseLifecycleProvider:g,cloudArtifactProvider:_}=e,v=o(i);switch(i.command){case t.artifacts:return{ok:!0,data:await f(i,s(i,l.get(c)),_)};case`lease_allocate`:{d(v.leaseProvider,m,h);let e=p.allocateLease(a(v)),t;try{t=await g?.allocate?.(e,u(i))}catch(t){throw p.releaseLease(n({leaseId:e.leaseId,tenantId:e.tenantId,runId:e.runId,leaseBackend:e.backend,leaseProvider:e.leaseProvider,deviceKey:e.deviceKey,clientId:e.clientId})),t}return{ok:!0,data:{lease:e,...t?{provider:t}:{}}}}case`lease_heartbeat`:{let e=p.heartbeatLease(r(v)),t=await g?.heartbeat?.(e,u(i));return{ok:!0,data:{lease:e,...t?{provider:t}:{}}}}case`lease_release`:{let e=n(v),t=p.getLease(e),r=t?await g?.release?.(t,u(i)):void 0;return{ok:!0,data:{released:p.releaseLease(e).released,...r?{provider:r}:{}}}}default:return null}}function u(e){return{flags:e.flags,cwd:typeof e.meta?.cwd==`string`?e.meta.cwd:void 0}}function d(t,n,r){if(!(!t||n===void 0||r===void 0||!r.includes(t)||n.includes(t)))throw new e(`UNSUPPORTED_OPERATION`,`Provider "${t}" is not available in this daemon runtime.`,{provider:t,hint:`Restart the daemon with ${t} configured, then retry lease allocation.`})}async function f(e,t,n){let r=g(e.flags,`providerSessionId`);return p(t,r)?await m(t.tenantId):await h(t,r,n)}function p(e,t){return i(e)||!e.leaseProvider&&!t}async function m(e){let t=await c(e);return{source:`daemon`,status:`ready`,artifacts:t,...t.length===0?{message:`No daemon artifacts available.`}:{}}}async function h(t,n,r){if(!t.leaseProvider)throw new e(`INVALID_ARGS`,`artifacts requires --provider for provider session lookup or an active cloud connection.`);if(!t.leaseId&&!n)throw new e(`INVALID_ARGS`,`artifacts requires an active cloud lease or --provider-session <id>.`);let i=await r?.listCloudArtifacts?.({provider:t.leaseProvider,leaseId:t.leaseId,providerSessionId:n});if(!i)throw new e(`UNSUPPORTED_OPERATION`,`Cloud artifacts are not available for provider "${t.leaseProvider}".`);return i}function g(e,t){let n=e?.[t];return typeof n==`string`&&n.length>0?n:void 0}export{l as handleLeaseCommands};
|
package/dist/src/limrun.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as DeviceTarget, D as Rect, E as RawSnapshotNode, H as PlatformSelector, R as DeviceInfo, T as Point, f as LeaseBackend, j as SnapshotOptions$1, k as SnapshotBackend } from "./sdk-contracts.js";
|
|
2
2
|
import { c as ScrollDirection, o as GesturePlan, r as AndroidAdbProvider } from "./sdk-android-adb.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { t as ClickButton } from "./click-button.js";
|
|
3
|
+
import { a as BackendSnapshotResult, d as DeviceRotation, f as BackMode, l as SessionSurface, n as CloudArtifactProvider, u as TvRemoteButton } from "./cloud-artifacts.js";
|
|
4
|
+
import { t as AppsFilter } from "./app-inventory.js";
|
|
5
|
+
import { n as AndroidKeyboardState, s as AndroidInputOwner, t as AndroidKeyboardDismissResult } from "./device-input-state.js";
|
|
7
6
|
import Limrun from "@limrun/api";
|
|
8
7
|
import "@limrun/api/instance-client";
|
|
9
8
|
import "@limrun/api/ios-client";
|
|
10
|
-
//#region src/
|
|
9
|
+
//#region packages/contracts/src/settings.d.ts
|
|
11
10
|
type SettingOptions = {
|
|
12
11
|
permissionTarget?: string;
|
|
13
12
|
permissionMode?: string;
|
|
@@ -15,18 +14,7 @@ type SettingOptions = {
|
|
|
15
14
|
longitude?: number;
|
|
16
15
|
};
|
|
17
16
|
//#endregion
|
|
18
|
-
//#region src/
|
|
19
|
-
type BackendSnapshotResult = {
|
|
20
|
-
nodes?: SnapshotNode[];
|
|
21
|
-
truncated?: boolean;
|
|
22
|
-
backend?: string;
|
|
23
|
-
snapshot?: SnapshotState;
|
|
24
|
-
appName?: string;
|
|
25
|
-
appBundleId?: string;
|
|
26
|
-
snapshotDiagnostics?: SnapshotDiagnosticsSummary;
|
|
27
|
-
} & SnapshotCaptureAnnotations;
|
|
28
|
-
//#endregion
|
|
29
|
-
//#region src/contracts/runner-lease-context.d.ts
|
|
17
|
+
//#region packages/contracts/src/runner-lease-context.d.ts
|
|
30
18
|
type RunnerLogicalLeaseContext = {
|
|
31
19
|
leaseId?: string;
|
|
32
20
|
clientId?: string;
|
|
@@ -36,9 +24,10 @@ type RunnerLogicalLeaseContext = {
|
|
|
36
24
|
deviceKey?: string;
|
|
37
25
|
};
|
|
38
26
|
//#endregion
|
|
39
|
-
//#region
|
|
27
|
+
//#region packages/contracts/src/interactor-types.d.ts
|
|
40
28
|
type RunnerContext = {
|
|
41
29
|
requestId?: string;
|
|
30
|
+
signal?: AbortSignal;
|
|
42
31
|
appBundleId?: string;
|
|
43
32
|
verbose?: boolean;
|
|
44
33
|
logPath?: string;
|
|
@@ -67,6 +56,7 @@ type ElementSelectorTapOptions = {
|
|
|
67
56
|
};
|
|
68
57
|
type SnapshotOptions = SnapshotOptions$1 & {
|
|
69
58
|
appBundleId?: string;
|
|
59
|
+
signal?: AbortSignal;
|
|
70
60
|
includeRects?: boolean;
|
|
71
61
|
includeHiddenContentHints?: boolean;
|
|
72
62
|
surface?: SessionSurface;
|
|
@@ -116,7 +106,7 @@ type Interactor = {
|
|
|
116
106
|
setSetting(setting: string, state: string, appId?: string, options?: SettingOptions): Promise<Record<string, unknown> | void>;
|
|
117
107
|
};
|
|
118
108
|
//#endregion
|
|
119
|
-
//#region
|
|
109
|
+
//#region packages/contracts/src/device-inventory.d.ts
|
|
120
110
|
type DeviceInventoryRequest = {
|
|
121
111
|
platform?: PlatformSelector;
|
|
122
112
|
target?: DeviceTarget;
|
|
@@ -131,7 +121,7 @@ type DeviceInventoryRequest = {
|
|
|
131
121
|
androidSerialAllowlist?: string[];
|
|
132
122
|
};
|
|
133
123
|
//#endregion
|
|
134
|
-
//#region
|
|
124
|
+
//#region packages/contracts/src/device-provider.d.ts
|
|
135
125
|
type DeviceLease = {
|
|
136
126
|
leaseId: string;
|
|
137
127
|
tenantId: string;
|
|
@@ -145,7 +135,8 @@ type DeviceLease = {
|
|
|
145
135
|
expiresAt: number;
|
|
146
136
|
};
|
|
147
137
|
type LeaseLifecycleContext = {
|
|
148
|
-
|
|
138
|
+
flags?: Readonly<Record<string, unknown>>;
|
|
139
|
+
cwd?: string;
|
|
149
140
|
};
|
|
150
141
|
type LeaseLifecycleProvider = {
|
|
151
142
|
allocate?: (lease: DeviceLease, context?: LeaseLifecycleContext) => Promise<Record<string, unknown> | undefined>;
|
|
@@ -154,137 +145,7 @@ type LeaseLifecycleProvider = {
|
|
|
154
145
|
};
|
|
155
146
|
type DeviceInventoryProvider = (request: DeviceInventoryRequest) => Promise<DeviceInfo[] | null | undefined>;
|
|
156
147
|
//#endregion
|
|
157
|
-
//#region src/
|
|
158
|
-
declare class Deadline {
|
|
159
|
-
private readonly startedAtMs;
|
|
160
|
-
private readonly expiresAtMs;
|
|
161
|
-
private constructor();
|
|
162
|
-
static fromTimeoutMs(timeoutMs: number, nowMs?: number): Deadline;
|
|
163
|
-
remainingMs(nowMs?: number): number;
|
|
164
|
-
elapsedMs(nowMs?: number): number;
|
|
165
|
-
isExpired(nowMs?: number): boolean;
|
|
166
|
-
}
|
|
167
|
-
//#endregion
|
|
168
|
-
//#region src/platforms/apple/core/runner/runner-cache.d.ts
|
|
169
|
-
type RunnerXctestrunCacheKind = 'exact' | 'restore-key' | 'miss' | 'external';
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region src/platforms/apple/core/runner/runner-artifact.d.ts
|
|
172
|
-
type RunnerXctestrunArtifactState = 'valid' | 'rebuilt';
|
|
173
|
-
type ExternalXctestRunnerOptions = {
|
|
174
|
-
iosXctestrunFile?: string;
|
|
175
|
-
iosXctestDerivedDataPath?: string;
|
|
176
|
-
iosXctestEnvDir?: string;
|
|
177
|
-
};
|
|
178
|
-
//#endregion
|
|
179
|
-
//#region src/platforms/apple/core/runner/runner-contract.d.ts
|
|
180
|
-
type RunnerCommand = {
|
|
181
|
-
command: 'tap' | 'mouseClick' | 'longPress' | 'drag' | 'remotePress' | 'type' | 'swipe' | 'scroll' | 'desktopScroll' | 'findText' | 'querySelector' | 'readText' | 'snapshot' | 'screenshot' | 'back' | 'backInApp' | 'backSystem' | 'home' | 'rotate' | 'gesture' | 'gestureViewport' | 'appSwitcher' | 'keyboardDismiss' | 'keyboardReturn' | 'alert' | 'sequence' | 'recordStart' | 'recordStop' | 'status' | 'uptime' | 'activate' | 'terminate' | 'targetReset' | 'shutdown';
|
|
182
|
-
commandId?: string;
|
|
183
|
-
statusCommandId?: string;
|
|
184
|
-
appBundleId?: string;
|
|
185
|
-
text?: string;
|
|
186
|
-
selectorKey?: ElementSelectorKey;
|
|
187
|
-
selectorValue?: string;
|
|
188
|
-
allowNonHittableCoordinateFallback?: boolean;
|
|
189
|
-
delayMs?: number;
|
|
190
|
-
textEntryMode?: 'append' | 'replace';
|
|
191
|
-
action?: 'get' | 'accept' | 'dismiss';
|
|
192
|
-
x?: number;
|
|
193
|
-
y?: number;
|
|
194
|
-
button?: ClickButton;
|
|
195
|
-
remoteButton?: 'select' | 'menu' | 'home' | 'up' | 'down' | 'left' | 'right';
|
|
196
|
-
x2?: number;
|
|
197
|
-
y2?: number;
|
|
198
|
-
durationMs?: number;
|
|
199
|
-
/** Remaining request budget for runner work that performs bounded XCTest queries. */
|
|
200
|
-
timeoutMs?: number;
|
|
201
|
-
direction?: ScrollDirection;
|
|
202
|
-
amount?: number;
|
|
203
|
-
pixels?: number;
|
|
204
|
-
orientation?: DeviceRotation;
|
|
205
|
-
/** Canonical pointer samples planned by the portable gesture runtime. */
|
|
206
|
-
gesturePlan?: GesturePlan;
|
|
207
|
-
outPath?: string;
|
|
208
|
-
fps?: number;
|
|
209
|
-
maxSize?: number;
|
|
210
|
-
interactiveOnly?: boolean;
|
|
211
|
-
depth?: number;
|
|
212
|
-
scope?: string;
|
|
213
|
-
raw?: boolean;
|
|
214
|
-
fullscreen?: boolean;
|
|
215
|
-
inlineScreenshot?: boolean;
|
|
216
|
-
synthesized?: boolean;
|
|
217
|
-
steps?: RunnerSequenceStep[];
|
|
218
|
-
};
|
|
219
|
-
/**
|
|
220
|
-
* One allowlisted coordinate gesture step inside a fused `sequence` runner command.
|
|
221
|
-
* The kind set is intentionally narrow (tap/doubleTap/longPress) and validated on both the
|
|
222
|
-
* daemon and runner sides — see runner-sequence.ts (the single interpretation point).
|
|
223
|
-
*/
|
|
224
|
-
type RunnerSequenceStep = {
|
|
225
|
-
kind: 'tap' | 'doubleTap' | 'longPress';
|
|
226
|
-
x: number;
|
|
227
|
-
y: number;
|
|
228
|
-
durationMs?: number;
|
|
229
|
-
pauseMs?: number;
|
|
230
|
-
/**
|
|
231
|
-
* For `tap` steps on iOS non-tv: use the synthesized HID tap (synthesizedTapAt) fast path
|
|
232
|
-
* instead of the drag-based XCUICoordinate tapAt, matching the individual `tap` command.
|
|
233
|
-
*/
|
|
234
|
-
synthesized?: boolean;
|
|
235
|
-
};
|
|
236
|
-
//#endregion
|
|
237
|
-
//#region src/platforms/apple/core/runner/runner-provider.d.ts
|
|
238
|
-
type AppleRunnerCommandOptions = ExternalXctestRunnerOptions & {
|
|
239
|
-
verbose?: boolean;
|
|
240
|
-
logPath?: string;
|
|
241
|
-
traceLogPath?: string;
|
|
242
|
-
cleanStaleBundles?: boolean;
|
|
243
|
-
startupTimeoutMs?: number;
|
|
244
|
-
requestId?: string;
|
|
245
|
-
runnerLeaseContext?: RunnerLogicalLeaseContext;
|
|
246
|
-
};
|
|
247
|
-
type AppleRunnerLifecycleOptions = AppleRunnerCommandOptions & {
|
|
248
|
-
buildTimeoutMs?: number;
|
|
249
|
-
forceRunnerXctestrunRebuild?: boolean;
|
|
250
|
-
};
|
|
251
|
-
type AppleRunnerPrewarmOptions = AppleRunnerLifecycleOptions;
|
|
252
|
-
type AppleRunnerPrepareOptions = AppleRunnerLifecycleOptions & {
|
|
253
|
-
healthTimeoutMs: number;
|
|
254
|
-
prepareDeadline?: Deadline;
|
|
255
|
-
};
|
|
256
|
-
type AppleRunnerPrepareResult = {
|
|
257
|
-
runner: Record<string, unknown>;
|
|
258
|
-
cache?: RunnerXctestrunCacheKind;
|
|
259
|
-
artifact?: RunnerXctestrunArtifactState;
|
|
260
|
-
buildMs?: number;
|
|
261
|
-
connectMs: number;
|
|
262
|
-
healthCheckMs: number;
|
|
263
|
-
xctestrunPath?: string;
|
|
264
|
-
recoveryReason?: string;
|
|
265
|
-
failureReason?: string;
|
|
266
|
-
};
|
|
267
|
-
type AppleRunnerCommandExecutor = (device: DeviceInfo, command: RunnerCommand, options: AppleRunnerCommandOptions) => Promise<Record<string, unknown>>;
|
|
268
|
-
type AppleRunnerPrepareExecutor = (device: DeviceInfo, options: AppleRunnerPrepareOptions) => Promise<AppleRunnerPrepareResult>;
|
|
269
|
-
type AppleRunnerPrewarmExecutor = (device: DeviceInfo, options: AppleRunnerPrewarmOptions) => Promise<void>;
|
|
270
|
-
type AppleRunnerProvider = {
|
|
271
|
-
/**
|
|
272
|
-
* Executes a runner protocol command for an already resolved Apple target.
|
|
273
|
-
* Scoped providers may adapt this call to a request-local transport.
|
|
274
|
-
*/
|
|
275
|
-
runCommand: AppleRunnerCommandExecutor;
|
|
276
|
-
/**
|
|
277
|
-
* Proves a runner can answer a cheap command after any required local setup.
|
|
278
|
-
* Command-only providers may omit this and let callers fall back to uptime.
|
|
279
|
-
*/
|
|
280
|
-
prepare?: AppleRunnerPrepareExecutor;
|
|
281
|
-
/**
|
|
282
|
-
* Starts runner setup opportunistically. This must remain best-effort.
|
|
283
|
-
*/
|
|
284
|
-
prewarm?: AppleRunnerPrewarmExecutor;
|
|
285
|
-
};
|
|
286
|
-
//#endregion
|
|
287
|
-
//#region src/provider-device-runtime.d.ts
|
|
148
|
+
//#region packages/contracts/src/provider-device-runtime.d.ts
|
|
288
149
|
type ProviderDeviceInstallResult = {
|
|
289
150
|
bundleId?: string;
|
|
290
151
|
packageName?: string;
|
|
@@ -296,6 +157,15 @@ type ProviderDeviceInstallOptions = {
|
|
|
296
157
|
appIdentifierHint?: string;
|
|
297
158
|
packageNameHint?: string;
|
|
298
159
|
};
|
|
160
|
+
type ProviderPortReverseOptions = {
|
|
161
|
+
leaseId: string;
|
|
162
|
+
provider?: string;
|
|
163
|
+
devicePort: number;
|
|
164
|
+
hostPort: number;
|
|
165
|
+
name: string;
|
|
166
|
+
};
|
|
167
|
+
type ProviderExpiredLeaseRecovery = (lease: DeviceLease) => Promise<void>;
|
|
168
|
+
/** Provider adapter contract; root owns active-runtime and request composition. */
|
|
299
169
|
type ProviderDeviceRuntime = {
|
|
300
170
|
provider: string;
|
|
301
171
|
leaseLifecycle: LeaseLifecycleProvider;
|
|
@@ -303,36 +173,73 @@ type ProviderDeviceRuntime = {
|
|
|
303
173
|
cloudArtifacts?: CloudArtifactProvider;
|
|
304
174
|
deviceInventoryProvider: DeviceInventoryProvider;
|
|
305
175
|
ownsDevice(device: DeviceInfo): boolean;
|
|
306
|
-
/**
|
|
307
|
-
* Builds the interactor for an owned device. `runnerContext` carries the
|
|
308
|
-
* per-request context (requestId for cancellation, appBundleId, log paths);
|
|
309
|
-
* runtimes composing the shared Apple interactor should thread it through so
|
|
310
|
-
* runner calls stay attributable to the request that issued them.
|
|
311
|
-
*/
|
|
312
176
|
getInteractor(device: DeviceInfo, runnerContext?: RunnerContext): Interactor | undefined;
|
|
313
|
-
/**
|
|
314
|
-
* Apple runner transport for an owned device. When present, the daemon scopes
|
|
315
|
-
* the WHOLE request with it (via the `appleRunnerProvider` request resolver),
|
|
316
|
-
* so daemon routes that issue runner commands outside interactor methods
|
|
317
|
-
* (keyboard, native alert, point read, iOS sequences) reach the provider
|
|
318
|
-
* transport instead of the local XCTest runtime.
|
|
319
|
-
*/
|
|
320
|
-
getAppleRunnerProvider?(device: DeviceInfo): AppleRunnerProvider | AppleRunnerCommandExecutor | undefined;
|
|
321
177
|
installApp?(device: DeviceInfo, app: string, appPath: string, options?: ProviderDeviceInstallOptions): Promise<ProviderDeviceInstallResult | undefined>;
|
|
322
178
|
installInstallablePath?(device: DeviceInfo, installablePath: string, options?: ProviderDeviceInstallOptions): Promise<ProviderDeviceInstallResult | undefined>;
|
|
323
179
|
configurePortReverse?(options: ProviderPortReverseOptions): Promise<Record<string, unknown> | undefined>;
|
|
324
180
|
shutdown(): Promise<void>;
|
|
325
181
|
};
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region packages/provider-limrun/src/runtime-dependencies.d.ts
|
|
184
|
+
type LimrunAdbCommandOptions = {
|
|
185
|
+
allowFailure?: boolean;
|
|
186
|
+
binaryStdout?: boolean;
|
|
187
|
+
stdin?: string | Buffer;
|
|
188
|
+
timeoutMs?: number;
|
|
189
|
+
signal?: AbortSignal;
|
|
190
|
+
};
|
|
191
|
+
type LimrunAdbCommandResult = {
|
|
192
|
+
exitCode: number;
|
|
193
|
+
stdout: string;
|
|
194
|
+
stderr: string;
|
|
195
|
+
stdoutBuffer?: Buffer;
|
|
196
|
+
};
|
|
197
|
+
type LimrunAdbExecutor = (args: string[], options?: LimrunAdbCommandOptions) => Promise<LimrunAdbCommandResult>;
|
|
198
|
+
type LimrunPortReverseEndpoint = `tcp:${number}` | `localabstract:${string}`;
|
|
199
|
+
type LimrunPortReverseMapping = {
|
|
200
|
+
local: LimrunPortReverseEndpoint;
|
|
201
|
+
remote: LimrunPortReverseEndpoint;
|
|
202
|
+
ownerId?: string;
|
|
203
|
+
};
|
|
204
|
+
type LimrunPortReverseOptions = {
|
|
205
|
+
signal?: AbortSignal;
|
|
206
|
+
timeoutMs?: number;
|
|
207
|
+
};
|
|
208
|
+
type LimrunPortReverse = {
|
|
209
|
+
ensure(mapping: LimrunPortReverseMapping, options?: LimrunPortReverseOptions): Promise<void>;
|
|
210
|
+
remove(local: LimrunPortReverseEndpoint, options?: LimrunPortReverseOptions): Promise<void>;
|
|
211
|
+
removeAllOwned(ownerId: string, options?: LimrunPortReverseOptions): Promise<void>;
|
|
212
|
+
list?(options?: LimrunPortReverseOptions): Promise<LimrunPortReverseMapping[]>;
|
|
213
|
+
};
|
|
214
|
+
type LimrunAdbProvider = {
|
|
215
|
+
exec: LimrunAdbExecutor;
|
|
216
|
+
reverse?: LimrunPortReverse;
|
|
217
|
+
text?: (request: {
|
|
218
|
+
action: 'type' | 'fill';
|
|
219
|
+
text: string;
|
|
220
|
+
delayMs?: number;
|
|
221
|
+
target?: {
|
|
222
|
+
x: number;
|
|
223
|
+
y: number;
|
|
224
|
+
};
|
|
225
|
+
}) => Promise<void>;
|
|
226
|
+
};
|
|
227
|
+
type LimrunAndroidKeyboardState = {
|
|
228
|
+
visible: boolean;
|
|
229
|
+
inputType?: string;
|
|
230
|
+
type?: 'text' | 'number' | 'email' | 'phone' | 'password' | 'datetime' | 'unknown';
|
|
231
|
+
inputMethodPackage?: string;
|
|
232
|
+
focusedPackage?: string;
|
|
233
|
+
focusedResourceId?: string;
|
|
234
|
+
inputOwner: AndroidInputOwner;
|
|
235
|
+
};
|
|
236
|
+
type LimrunAndroidKeyboardDismissResult = LimrunAndroidKeyboardState & {
|
|
237
|
+
attempts: number;
|
|
238
|
+
wasVisible: boolean;
|
|
239
|
+
dismissed: boolean;
|
|
332
240
|
};
|
|
333
|
-
type ProviderExpiredLeaseRecovery = (lease: DeviceLease) => Promise<void>;
|
|
334
241
|
//#endregion
|
|
335
|
-
//#region
|
|
242
|
+
//#region packages/provider-limrun/src/ios.d.ts
|
|
336
243
|
type LimrunIosRemoteInstallOptions = {
|
|
337
244
|
md5?: string;
|
|
338
245
|
relaunch?: boolean;
|
|
@@ -342,7 +249,7 @@ type LimrunIosRemoteInstallResult = {
|
|
|
342
249
|
appId?: string;
|
|
343
250
|
};
|
|
344
251
|
//#endregion
|
|
345
|
-
//#region
|
|
252
|
+
//#region packages/provider-limrun/src/device-session.d.ts
|
|
346
253
|
type LimrunRecordingQuality = 5 | 6 | 7 | 8 | 9 | 10;
|
|
347
254
|
type LimrunInstalledApp = {
|
|
348
255
|
id: string;
|
|
@@ -381,12 +288,12 @@ type LimrunDeviceSessionBase = {
|
|
|
381
288
|
outPath: string;
|
|
382
289
|
}): Promise<string>;
|
|
383
290
|
};
|
|
384
|
-
type LimrunAndroidDeviceSession = LimrunDeviceSessionBase & {
|
|
291
|
+
type LimrunAndroidDeviceSession$1 = LimrunDeviceSessionBase & {
|
|
385
292
|
readonly platform: 'android';
|
|
386
|
-
readonly adb:
|
|
293
|
+
readonly adb: LimrunAdbProvider;
|
|
387
294
|
getForegroundApp(): Promise<LimrunForegroundApp | undefined>;
|
|
388
|
-
getKeyboardState(): Promise<
|
|
389
|
-
dismissKeyboard(): Promise<
|
|
295
|
+
getKeyboardState(): Promise<LimrunAndroidKeyboardState>;
|
|
296
|
+
dismissKeyboard(): Promise<LimrunAndroidKeyboardDismissResult>;
|
|
390
297
|
readLogs(lineLimit: number): Promise<string>;
|
|
391
298
|
installRemoteApp(url: string): Promise<void>;
|
|
392
299
|
};
|
|
@@ -400,22 +307,29 @@ type LimrunIosDeviceSession = LimrunDeviceSessionBase & {
|
|
|
400
307
|
installRemoteApp(url: string, options?: LimrunIosRemoteInstallOptions): Promise<LimrunIosRemoteInstallResult>;
|
|
401
308
|
runSimctl(args: string[]): LimrunIosCommandExecution;
|
|
402
309
|
};
|
|
403
|
-
type LimrunDeviceSession = LimrunAndroidDeviceSession | LimrunIosDeviceSession;
|
|
404
310
|
//#endregion
|
|
405
|
-
//#region
|
|
311
|
+
//#region packages/provider-limrun/src/runtime.d.ts
|
|
406
312
|
type LimrunRuntimeOptions = {
|
|
407
313
|
apiKey: string;
|
|
408
314
|
region?: string;
|
|
409
315
|
};
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region src/sdk/limrun-runtime-types.d.ts
|
|
318
|
+
type LimrunAndroidDeviceSession = Omit<LimrunAndroidDeviceSession$1, 'adb' | 'getKeyboardState' | 'dismissKeyboard'> & {
|
|
319
|
+
readonly adb: AndroidAdbProvider;
|
|
320
|
+
getKeyboardState(): Promise<AndroidKeyboardState>;
|
|
321
|
+
dismissKeyboard(): Promise<AndroidKeyboardDismissResult>;
|
|
322
|
+
};
|
|
323
|
+
type LimrunDeviceSession = LimrunAndroidDeviceSession | LimrunIosDeviceSession;
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/provider-limrun-runtime.d.ts
|
|
410
326
|
declare class LimrunRuntime implements ProviderDeviceRuntime {
|
|
411
|
-
private readonly
|
|
412
|
-
private readonly sessions;
|
|
413
|
-
private readonly options;
|
|
327
|
+
private readonly implementation;
|
|
414
328
|
readonly provider = "limrun";
|
|
415
|
-
readonly leaseLifecycle: LeaseLifecycleProvider;
|
|
416
|
-
readonly recoverExpiredLease: ProviderExpiredLeaseRecovery;
|
|
417
|
-
readonly deviceInventoryProvider: DeviceInventoryProvider;
|
|
418
329
|
constructor(options: LimrunRuntimeOptions);
|
|
330
|
+
get leaseLifecycle(): LeaseLifecycleProvider;
|
|
331
|
+
get recoverExpiredLease(): ProviderExpiredLeaseRecovery;
|
|
332
|
+
get deviceInventoryProvider(): DeviceInventoryProvider;
|
|
419
333
|
ownsDevice(device: DeviceInfo): boolean;
|
|
420
334
|
getInteractor(device: DeviceInfo): Interactor | undefined;
|
|
421
335
|
getDeviceSession(device: DeviceInfo): LimrunDeviceSession | undefined;
|
|
@@ -423,15 +337,6 @@ declare class LimrunRuntime implements ProviderDeviceRuntime {
|
|
|
423
337
|
installInstallablePath(device: DeviceInfo, installablePath: string, options?: ProviderDeviceInstallOptions): Promise<ProviderDeviceInstallResult | undefined>;
|
|
424
338
|
configurePortReverse(options: ProviderPortReverseOptions): Promise<Record<string, unknown> | undefined>;
|
|
425
339
|
shutdown(): Promise<void>;
|
|
426
|
-
private allocate;
|
|
427
|
-
private createIosSession;
|
|
428
|
-
private createAndroidSession;
|
|
429
|
-
private buildInstanceMetadata;
|
|
430
|
-
private release;
|
|
431
|
-
private releaseRecoveredSession;
|
|
432
|
-
private terminateSession;
|
|
433
|
-
private getSessionForDevice;
|
|
434
|
-
private requireAndroidPortReverseSession;
|
|
435
340
|
}
|
|
436
341
|
//#endregion
|
|
437
|
-
export { type
|
|
342
|
+
export { type LimrunAndroidDeviceSession, type LimrunDeviceSession, type LimrunIosCommandExecution, type LimrunIosDeviceSession, LimrunRuntime, type LimrunRuntimeOptions };
|
package/dist/src/limrun.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./
|
|
1
|
+
import{t as e}from"./provider-limrun-runtime.js";export{e as LimrunRuntime};
|
package/dist/src/linux.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{w as t}from"./screenshot-geometry.js";import{I as n}from"./sdk-android-adb.js";import{t as r}from"./snapshot.js";import{t as i}from"./tool-provider2.js";import{doubleClickLinux as a,fillLinux as o,focusLinux as s,longPressLinux as c,pressLinux as l,scrollLinux as u,sendKey as d,swipeLinux as f,typeLinux as p}from"./input-actions2.js";async function m(e){await i().desktop.openTarget(e)}async function h(e){await i().desktop.closeApp(e)}async function g(){await d(`alt+Left`,[`56:1`,`105:1`,`105:0`,`56:0`])}async function _(){await d(`super+d`,[`125:1`,`32:1`,`32:0`,`125:0`])}async function v(){return await i().clipboard.readText()}async function y(e){await i().clipboard.writeText(e)}async function b(e,t){await i().screenshot.capture(e,t)}function x(){return{open:e=>m(e),openDevice:()=>Promise.resolve(),close:e=>h(e),tap:(e,t)=>l(e,t),doubleTap:(e,t)=>a(e,t),longPress:(e,t,n)=>c(e,t,n),focus:(e,t)=>s(e,t),type:(e,t)=>p(e,t),fill:(e,t,n,r)=>o(e,t,n,r),scroll:(e,t)=>u(e,t),performGesture:async n=>{if(n.topology===`two`)throw new e(`UNSUPPORTED_OPERATION`,`Multi-touch gestures are not supported on Linux`);let{start:r,end:i}=t(n);await f(r.x,r.y,i.x,i.y,n.durationMs)},screenshot:(e,t)=>b(e,t),snapshot:async e=>{let t=await n(`snapshot_capture`,async()=>await r(e?.surface,e?.signal),{backend:`linux-atspi`});return{nodes:t.nodes??[],truncated:t.truncated??!1,backend:`linux-atspi`}},back:()=>g(),home:()=>_(),setOrientation:()=>{throw new e(`UNSUPPORTED_OPERATION`,`orientation not supported on Linux`)},appSwitcher:()=>{throw new e(`UNSUPPORTED_OPERATION`,`appSwitcher not yet supported on Linux`)},tvRemote:()=>{throw new e(`UNSUPPORTED_OPERATION`,`tv-remote not supported on Linux`)},readClipboard:()=>v(),writeClipboard:e=>y(e),setSetting:()=>{throw new e(`UNSUPPORTED_OPERATION`,`setSetting not supported on Linux`)}}}export{x as createLinuxInteractor};
|
package/dist/src/logcat.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{n}from"./sdk-android-adb.js";import"node:fs";var r=e({captureAndroidLogcatWithAdb:()=>i,streamAndroidLogcatWithAdb:()=>a});async function i(e,t={}){let r=[`logcat`,`-d`,`-v`,`time`];t.lines!==void 0&&r.push(`-t`,String(Math.max(1,Math.floor(t.lines))));let i=await e(r,{allowFailure:!0,timeoutMs:t.timeoutMs,signal:t.signal});if(i.exitCode!==0)throw n(`Failed to capture Android logcat`,i);return i.stdout}function a(e,n={}){if(!e.spawn)throw new t(`UNSUPPORTED_OPERATION`,`Android ADB provider does not support streams`,{capability:`adb.spawn`});let r=[`logcat`,`-v`,`time`];n.pid&&r.push(`--pid`,n.pid);let i=e.spawn(r,{stdio:[`ignore`,`pipe`,`pipe`],signal:n.signal});return n.output&&i.stdout&&i.stdout.pipe(n.output,{end:!1}),i}export{r as n,a as r,i as t};
|
package/dist/src/manifest.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{m as e,v as t}from"./sdk-android-adb.js";import
|
|
1
|
+
import{m as e,v as t}from"./sdk-android-adb.js";import n from"node:path";import{TextDecoder as r}from"node:util";import{promises as i}from"node:fs";import a from"node:os";import o from"node:fs/promises";const s=[`emulator`,`platform-tools`,n.join(`cmdline-tools`,`latest`,`bin`),n.join(`cmdline-tools`,`tools`,`bin`)];function c(e){let t=new Set,n=[];for(let r of e){let e=r.trim();!e||t.has(e)||(t.add(e),n.push(e))}return n}function l(e=process.env){let t=e.ANDROID_SDK_ROOT?.trim(),r=e.ANDROID_HOME?.trim(),i=e.HOME?.trim()||a.homedir(),o=i?n.join(i,`Android`,`Sdk`):``;return c([t??``,r??``,o])}async function u(e){try{return await i.access(e,i.constants.X_OK),!0}catch{return!1}}async function d(e=process.env){let t=[],r;for(let i of l(e)){let e=[];for(let t of s){let r=n.join(i,t);await u(r)&&e.push(r)}e.length!==0&&(r||=i,t.push(...e))}if(r&&(e.ANDROID_SDK_ROOT=e.ANDROID_SDK_ROOT?.trim()||r,e.ANDROID_HOME=e.ANDROID_HOME?.trim()||r),t.length===0)return;let i=(e.PATH??``).split(n.delimiter).map(e=>e.trim()).filter(e=>e.length>0);e.PATH=c([...t,...i]).join(n.delimiter)}const f=new r(`utf-16le`);let p;async function m(e){for(let t of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let n=await h(e,t);if(!n)continue;let r=g(n);if(r)return r}return await T(e)}async function h(e,n){try{let r=await t(`unzip`,[`-p`,e,n],{allowFailure:!0,binaryStdout:!0});return r.exitCode!==0||!r.stdoutBuffer||r.stdoutBuffer.length===0?void 0:r.stdoutBuffer}catch{return}}function g(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?_(e.toString(`utf8`)):v(e)}function _(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function v(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t;for(let n=e.readUInt16LE(2);n+8<=e.length;){let r=e.readUInt16LE(n),i=e.readUInt16LE(n+2),a=e.readUInt32LE(n+4);if(a<=0||n+a>e.length)return;if(r===1)t=b(e.subarray(n,n+a));else if(r===258&&t){let r=y(e,n,i,t);if(r)return r}n+=a}}function y(e,t,n,r){if(n<36||t+n>e.length||r[e.readUInt32LE(t+20)]!==`manifest`)return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)return;if(r[e.readUInt32LE(n+4)]!==`package`)continue;let i=e.readUInt32LE(n+8);if(i!==4294967295)return r[i];let o=e.readUInt8(n+15),c=e.readUInt32LE(n+16);return o===3?r[c]:void 0}}function b(e){if(e.length<28)return[];let t=e.readUInt32LE(8),n=e.readUInt32LE(16),r=e.readUInt32LE(20),i=(n&256)!=0,a=[];for(let n=0;n<t;n+=1){let t=28+n*4;if(t+4>e.length)return a;let o=r+e.readUInt32LE(t);a.push(i?x(e,o):S(e,o))}return a}function x(e,t){let[,n]=C(e,t),[r,i]=C(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString(`utf8`)}function S(e,t){let[n,r]=w(e,t),i=t+r;return f.decode(e.subarray(i,i+n*2))}function C(e,t){let n=e.readUInt8(t);if(!(n&128))return[n,1];let r=e.readUInt8(t+1);return[(n&127)<<8|r,2]}function w(e,t){let n=e.readUInt16LE(t);if(!(n&32768))return[n,2];let r=e.readUInt16LE(t+2);return[(n&32767)<<16|r,4]}async function T(e){let n=await E();if(!n)return;let r=await t(n,[`dump`,`badging`,e],{allowFailure:!0});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function E(){if(p!==void 0)return p??void 0;try{for(let t of l()){let r=n.join(t,`build-tools`);try{let t=(await o.readdir(r)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let i of t){let t=n.join(r,i,`aapt`);if(n.isAbsolute(t)&&await e(t))return p=t,t}}catch{}}}catch{}p=null}export{d as n,m as t};
|
package/dist/src/metro.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as SessionRuntimeHints } from "./sdk-contracts.js";
|
|
2
2
|
import { d as PrepareMetroRuntimeResult, f as ReloadMetroResult, o as MetroPrepareKind, p as MetroBridgeScope } from "./sdk-remote-config.js";
|
|
3
3
|
//#region src/utils/url.d.ts
|
|
4
4
|
declare function normalizeBaseUrl(input: string): string;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./entities.js";const t=new Set(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.:-`),n=new Set([` `,` `,`
|
|
2
|
+
`,`\r`]),r=new Set([`__defineGetter__`,`__defineSetter__`,`__proto__`,`constructor`,`prototype`]);function i(e,t={}){let n=t.maxDocumentChars??134217728;if(e.length>n)throw Error(`XML document exceeds maximum supported size of ${n} characters.`);return new a(e).parse()}var a=class{roots=[];stack=[];index=0;xml;constructor(e){this.xml=e}parse(){for(this.skipByteOrderMark();this.index<this.xml.length;)this.readNextToken();return this.assertFullyClosed(),this.roots}readNextToken(){if(this.xml[this.index]!==`<`){this.readText();return}this.resolveMarkupReader()()}resolveMarkupReader(){return this.startsWith(`<!--`)?()=>this.skipUntil(`-->`,`Comment is not closed.`):this.startsWith(`<?`)?()=>this.skipUntil(`?>`,`Processing instruction is not closed.`):this.startsWith(`<![CDATA[`)?()=>this.readCdata():this.startsWith(`<!`)?()=>this.skipDeclaration():this.startsWith(`</`)?()=>this.readClosingTag():()=>this.readOpeningTag()}assertFullyClosed(){if(this.stack.length>0){let e=this.stack[this.stack.length-1];throw Error(`Unclosed XML tag <${e?.name??`unknown`}>.`)}}skipByteOrderMark(){this.xml.charCodeAt(0)===65279&&(this.index=1)}readOpeningTag(){this.index+=1,this.skipWhitespace();let e=this.readRequiredName(`Missing XML tag name at offset ${this.index}.`),{attributes:t,selfClosing:n}=this.readOpeningTagBody(),r={name:e,attributes:t,text:null,children:[]};this.addNode(r),n||this.pushOpenNode(r)}readOpeningTagBody(){let e={};for(;;){this.skipWhitespace();let t=this.readOpeningTagEnd();if(t)return{attributes:e,selfClosing:t===`self-closing`};let n=this.readAttribute();e[n.name]=n.value}}readOpeningTagEnd(){if(this.index>=this.xml.length)throw Error(`Opening XML tag is not closed.`);return this.xml[this.index]===`>`?(this.index+=1,`open`):this.xml[this.index]===`/`&&this.xml[this.index+1]===`>`?(this.index+=2,`self-closing`):null}readAttribute(){let e=this.readRequiredName(`Invalid XML attribute at offset ${this.index}.`);if(f(e),this.skipWhitespace(),this.xml[this.index]!==`=`)throw Error(`Missing value for XML attribute "${e}".`);return this.index+=1,this.skipWhitespace(),{name:e,value:this.readAttributeValue(e)}}pushOpenNode(e){if(this.stack.length>=256)throw Error(`Maximum XML nesting depth of 256 exceeded.`);this.stack.push(e)}readClosingTag(){this.index+=2,this.skipWhitespace();let e=this.readName();if(this.skipWhitespace(),this.xml[this.index]!==`>`)throw Error(`Closing XML tag </${e}> is not closed.`);this.index+=1;let t=this.stack.pop();if(!t)throw Error(`Unexpected closing XML tag </${e}>.`);if(t.name!==e)throw Error(`Expected </${t.name}> before </${e}>.`)}readText(){let e=this.xml.indexOf(`<`,this.index),t=e===-1?this.xml.length:e;this.appendText(this.xml.slice(this.index,t),!0),this.index=t}readCdata(){let e=this.index+9,t=this.xml.indexOf(`]]>`,e);if(t===-1)throw Error(`CDATA section is not closed.`);this.appendText(this.xml.slice(e,t),!1),this.index=t+3}appendText(t,n){let r=t.trim();if(!r)return;let i=this.stack[this.stack.length-1];i&&(i.text=`${i.text??``}${n?e(r):r}`)}addNode(e){let t=this.stack[this.stack.length-1];t?t.children.push(e):this.roots.push(e)}readName(){let e=this.index;for(;this.index<this.xml.length&&o(this.xml[this.index]);)this.index+=1;return this.xml.slice(e,this.index)}readRequiredName(e){let t=this.readName();if(!t)throw Error(e);return t}readAttributeValue(t){let n=this.xml[this.index];if(n!==`"`&&n!==`'`)throw Error(`XML attribute "${t}" must use a quoted value.`);this.index+=1;let r=this.index,i=this.xml.indexOf(n,r);if(i===-1)throw Error(`XML attribute "${t}" is not closed.`);return this.index=i+1,e(this.xml.slice(r,i).trim())}skipDeclaration(){let e={quote:null,bracketDepth:0};for(let t=this.index+2;t<this.xml.length;t+=1)if(c(e,this.xml[t])){this.index=t+1;return}throw Error(`XML declaration is not closed.`)}skipUntil(e,t){let n=this.xml.indexOf(e,this.index+e.length);if(n===-1)throw Error(t);this.index=n+e.length}skipWhitespace(){for(;this.index<this.xml.length&&s(this.xml[this.index]);)this.index+=1}startsWith(e){return this.xml.startsWith(e,this.index)}};function o(e){return e!==void 0&&t.has(e)}function s(e){return e!==void 0&&n.has(e)}function c(e,t){return t===void 0||l(e,t)?!1:(u(e,t),d(e,t))}function l(e,t){return e.quote?(t===e.quote&&(e.quote=null),!0):t===`"`||t===`'`?(e.quote=t,!0):!1}function u(e,t){if(t===`[`){e.bracketDepth+=1;return}t===`]`&&e.bracketDepth>0&&--e.bracketDepth}function d(e,t){return t===`>`&&e.bracketDepth===0}function f(e){if(r.has(e))throw Error(`Unsupported XML attribute name "${e}".`)}export{i as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"node:
|
|
1
|
+
import e from"node:path";import t from"node:os";function n(e){return e?.HOME?.trim()||t.homedir()}function r(t,r={}){return t===`~`?n(r.env):t.startsWith(`~/`)?e.join(n(r.env),t.slice(2)):t}function i(t,n={}){let i=r(t,n);return e.isAbsolute(i)?i:e.resolve(n.cwd??process.cwd(),i)}export{i as n,r as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{C as t,j as n,p as r}from"./sdk-android-adb.js";import{n as i,t as a}from"./version.js";import{c as o,g as s,o as c,s as ee}from"./sdk-device.js";import{c as te,o as ne,s as re}from"./boot-diagnostics.js";import{a as l,s as ie}from"./tool-provider.js";import u from"node:crypto";import d,{promises as f}from"node:fs";import p from"node:os";import m from"node:path";function h(e,t={}){let n=ne(t.simulatorSetPath);return n?[`simctl`,`--set`,n,...e]:[`simctl`,...e]}function g(e,t){return!ee(e)||e.kind!==`simulator`?[`simctl`,...t]:h(t,{simulatorSetPath:e.simulatorSetPath})}function ae(e,t,n){return l(g(e,t),n)}const _={iOS:{sdkName:{simulator:`iphonesimulator`,device:`iphoneos`},derivedBaseName:{simulator:`ios-simulator`,device:`ios-device`},xctestrunHints:{simulator:{preferred:[`iphonesimulator`],disallowed:[`iphoneos`,`appletvos`,`appletvsimulator`,`macos`]},device:{preferred:[`iphoneos`],disallowed:[`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]}}},tvOS:{sdkName:{simulator:`appletvsimulator`,device:`appletvos`},derivedBaseName:{simulator:`tvos-simulator`,device:`tvos-device`},xctestrunHints:{simulator:{preferred:[`appletvsimulator`],disallowed:[`appletvos`,`iphoneos`,`iphonesimulator`,`macos`]},device:{preferred:[`appletvos`],disallowed:[`appletvsimulator`,`iphoneos`,`iphonesimulator`,`macos`]}}},macOS:{sdkName:{simulator:`macosx`,device:`macosx`},derivedBaseName:{simulator:`macos`,device:`macos`},xctestrunHints:{simulator:{preferred:[`macos`],disallowed:[`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`]},device:{preferred:[`macos`],disallowed:[`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`]}}},visionOS:{sdkName:{simulator:`xrsimulator`,device:`xros`},derivedBaseName:{simulator:`visionos-simulator`,device:`visionos-device`},xctestrunHints:{simulator:{preferred:[`xrsimulator`],disallowed:[`xros`,`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]},device:{preferred:[`xros`],disallowed:[`xrsimulator`,`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]}}}};function v(t){if(!c(t.platform))throw new e(`UNSUPPORTED_PLATFORM`,`Unsupported platform for Apple runner: ${t.platform}`);return o(t)?`macOS`:s(t.target,t.appleOs)}function oe(e,t){return _[e].sdkName[y(t)]}function se(e){return _[v(e)].derivedBaseName[y(e.kind)]}function ce(e){return _[v(e)].xctestrunHints[y(e.kind)]}function le(e){let t=v(e);return t===`macOS`?`platform=macOS,arch=${b()}`:e.kind===`simulator`?`platform=${t} Simulator,id=${e.id}`:`platform=${t},id=${e.id}`}function ue(e){let t=v(e);return t===`macOS`?`platform=macOS,arch=${b()}`:e.kind===`simulator`?`platform=${t} Simulator,id=${e.id}`:`generic/platform=${t}`}function de(e){let t=v(e);return t===`macOS`?`platform=macOS,arch=${b()}`:e.kind===`simulator`?`generic/platform=${t} Simulator`:`generic/platform=${t}`}function y(e){return e===`simulator`?`simulator`:`device`}function b(){return process.arch===`arm64`?`arm64`:`x86_64`}const fe=new Set;function x(e={}){let t=new Map,n=e.now??(()=>Date.now()),r=e=>{e?.timer&&clearTimeout(e.timer)},i={get(e){let r=t.get(e);if(r){if(r.expiresAt!==void 0&&r.expiresAt<=n()){i.delete(e);return}return r.value}},set(i,a){r(t.get(i));let o=pe(e.ttlMs,n),s={value:a,expiresAt:o};e.scheduleExpiry&&o!==void 0&&(s.timer=setTimeout(()=>{t.delete(i)},Math.max(0,o-n())),s.timer.unref?.()),t.set(i,s)},delete(e){let n=t.get(e);return n?(r(n),t.delete(e)):!1},clear(){for(let e of t.values())r(e);t.clear()}};return fe.add(i.clear),i}function pe(e,t){if(!(e===void 0||!Number.isFinite(e)))return t()+Math.max(0,e)}const me=m.join(`apple`,`runner`,`AgentDeviceRunner`),he=m.join(`dist`,`apple`,`runner`,`AgentDeviceRunner`);function S(e){let t=m.join(e,me);return d.existsSync(t)?t:m.join(e,he)}function ge(e){return m.join(S(e),`AgentDeviceRunner.xcodeproj`)}const _e=m.join(p.homedir(),`.agent-device`,`apple-runner`),ve=`.agent-device-runner-cache.json`,ye=[`-IDEPackageSupportDisableManifestSandbox=1`,`-IDEPackageSupportDisablePluginExecutionSandbox=1`,`ENABLE_USER_SCRIPT_SANDBOXING=NO`],C=x();function w(e){return e?.trim()??``}function T(e=process.env){return w(e.AGENT_DEVICE_IOS_BUNDLE_ID)||w(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||`com.callstack.agentdevice.runner`}function E(e=process.env){return w(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID)||`${T(e)}.uitests`}function be(e=process.env){let t=T(e),n=E(e);return Array.from(new Set([w(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}const D=be(process.env);function xe(e,t=a()){let n=v(e);return{schemaVersion:2,packageVersion:i(t),runnerSourceFingerprint:Oe(t),...Se(n,e.kind),platformName:n,deviceKind:e.kind,target:e.target??`mobile`,buildDestinationFamily:de(e),runnerBundleBuildSettings:N(process.env),runnerSigningBuildSettings:M(process.env,e.kind===`device`,e),runnerPerformanceBuildSettings:P(),runnerSandboxBuildArgs:F()}}function Se(e,t){let n=Ce(O(`xcodebuild`,[`-version`])),r=oe(e,t);return{xcodeVersion:n.version,xcodeBuildVersion:n.buildVersion,sdkName:r,sdkVersion:O(`xcrun`,[`--sdk`,r,`--show-sdk-version`]),sdkBuildVersion:O(`xcrun`,[`--sdk`,r,`--show-sdk-build-version`])}}function O(e,n){let r=JSON.stringify([e,n]),i=C.get(r);if(i!==void 0)return i;try{let i=t(e,n,{allowFailure:!0,timeoutMs:5e3,maxBuffer:128*1024}),a=i.exitCode===0&&i.stdout.trim()||`unknown`;return C.set(r,a),a}catch{return C.set(r,`unknown`),`unknown`}}function Ce(e){return{version:e.match(/^Xcode\s+(.+)$/m)?.[1]?.trim()||`unknown`,buildVersion:e.match(/^Build version\s+(.+)$/m)?.[1]?.trim()||`unknown`}}function we(e,t){let n=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim();if(n)return m.resolve(n);let r=Ee(t),i=Te(e);return m.join(i,r)}function Te(e){return m.join(_e,`derived`,se(e))}function Ee(e){return`cache-${u.createHash(`sha256`).update(De(k(e))).digest(`hex`).slice(0,16)}`}function k(e){let{artifacts:t,packageVersion:n,...r}=e;return r}function De(e){return JSON.stringify(A(e))}function A(e){return Array.isArray(e)?e.map(e=>A(e)):!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,A(t)]))}const j=new Map;function Oe(e){let t=S(e),n=Ae(t),r=ke(t,n),i=j.get(t);if(i?.fileStatsFingerprint===r)return i.sourceFingerprint;let a=u.createHash(`sha256`);for(let e of n){let n=m.relative(t,e);a.update(n),a.update(`\0`),a.update(d.readFileSync(e)),a.update(`\0`)}let o=a.digest(`hex`);return j.set(t,{fileStatsFingerprint:r,sourceFingerprint:o}),o}function ke(e,t){let n=u.createHash(`sha256`);for(let r of t){let t=m.relative(e,r),i=d.statSync(r);n.update(t),n.update(`\0`),n.update(String(i.size)),n.update(`\0`),n.update(String(Math.trunc(i.mtimeMs))),n.update(`\0`)}return n.digest(`hex`)}function Ae(e){if(!d.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of d.readdirSync(e,{withFileTypes:!0})){let i=m.join(e,r.name);if(r.isDirectory()){if(r.name===`xcuserdata`)continue;n.push(i);continue}r.isFile()&&je(r.name,i)&&t.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}function je(e,t){return e===`project.pbxproj`?t.includes(`${m.sep}.xcodeproj${m.sep}`):[`.jpg`,`.json`,`.png`,`.swift`,`.m`,`.h`,`.plist`,`.entitlements`,`.xctestplan`,`.xcconfig`,`.storyboard`,`.xib`].includes(m.extname(e))}function Me(e){return o(e)||e.kind===`device`?`-maximum-concurrent-test-device-destinations`:`-maximum-concurrent-test-simulator-destinations`}function M(e=process.env,t=!1,n={platform:`apple`}){if(o(n))return[`CODE_SIGNING_ALLOWED=NO`,`CODE_SIGNING_REQUIRED=NO`,`CODE_SIGN_IDENTITY=`,`DEVELOPMENT_TEAM=`];if(!t)return[];let r=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||``,i=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||``,a=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||``,s=[`CODE_SIGN_STYLE=Automatic`];return r&&s.push(`DEVELOPMENT_TEAM=${r}`),i&&s.push(`CODE_SIGN_IDENTITY=${i}`),a&&s.push(`PROVISIONING_PROFILE_SPECIFIER=${a}`),s}function N(e=process.env){let t=T(e),n=E(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}function P(){return[`COMPILER_INDEX_STORE_ENABLE=NO`,`ENABLE_CODE_COVERAGE=NO`,`ONLY_ACTIVE_ARCH=YES`,`ENABLE_PREVIEWS=NO`,`ENABLE_DEBUG_DYLIB=NO`]}function F(){return[...ye,`OTHER_SWIFT_FLAGS=${Ne(process.env)}`]}function Ne(e){return te(e.AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS)?`$(inherited) -disable-sandbox -D AGENT_DEVICE_RUNNER_UNIT_TESTS`:`$(inherited) -disable-sandbox`}const Pe=18e4,Fe=6e4,Ie=6e4,Le=1e4,Re=15e3,ze=2e4,Be=15e3,I=2e4,Ve=1e3,He=5e3;async function L(t,n,i={}){let a=[`devicectl`,...t],o=await l(a,{allowFailure:!0,timeoutMs:i.timeoutMs??2e4});if(o.exitCode===0)return;let{stdout:s,stderr:c}=o;if(!i.tolerateOutput?.(s,c))throw new e(`COMMAND_FAILED`,`Failed to ${n.action}`,r(o,{cmd:`xcrun`,args:a,stdout:s,stderr:c,deviceId:n.deviceId,hint:G(s,c)??`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`}))}async function R(e,t){return Ye(qe(await B(e,{jsonPrefix:`agent-device-ios-apps`,args:[`devicectl`,`device`,`info`,`apps`,`--device`,e.id,`--include-all-apps`],failureMessage:`Failed to list iOS apps`,parseFailureMessage:`Failed to parse iOS apps list`})),t)}async function Ue(t){let n=await B(t,{jsonPrefix:`agent-device-ios-processes`,args:[`devicectl`,`device`,`info`,`processes`,`--device`,t.id],failureMessage:`Failed to list iOS processes`,parseFailureMessage:`Failed to parse iOS process list`,fallbackHint:W});if(!Ge(n))throw new e(`COMMAND_FAILED`,`Unsupported iOS process list response`,{deviceId:t.id,hint:W});return Je(n)}async function We(e,t){let{appBundleUrl:n,processes:r}=await z(e,t),i=r.sort((e,t)=>H(e,n)-H(t,n))[0];i&&await B(e,{jsonPrefix:`agent-device-ios-process-terminate`,args:[`devicectl`,`device`,`process`,`terminate`,`--device`,e.id,`--pid`,String(i.pid),`--kill`],failureMessage:`Failed to terminate iOS app`,parseFailureMessage:`Failed to parse iOS process termination response`,tolerateFailurePayload:Ke})}async function z(t,n){let r=(await R(t,`all`)).find(e=>e.bundleId===n);if(!r)throw new e(`APP_NOT_INSTALLED`,`No iOS device app found for ${n}`,{appBundleId:n,deviceId:t.id});if(!r.url)throw new e(`COMMAND_FAILED`,`Missing app bundle URL for ${n}`,{appBundleId:n,deviceId:t.id,hint:`Installed-app metadata from devicectl did not include the bundle URL required to match running processes. Use an Xcode/CoreDevice toolchain that reports app URLs.`});let i=r.url.replace(/\/+$/,``);return{appBundleUrl:i,processes:(await Ue(t)).filter(e=>e.executable.startsWith(`${i}/`))}}async function B(t,n){let i=m.join(p.tmpdir(),`${n.jsonPrefix}-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),a=[...n.args,`--json-output`,i],o=await l(a,{allowFailure:!0,timeoutMs:2e4});try{if(o.exitCode!==0){let{stdout:s,stderr:c}=o;if(n.tolerateFailurePayload){let e=await V(i).catch(()=>void 0);if(e!==void 0&&n.tolerateFailurePayload(e))return e}throw new e(`COMMAND_FAILED`,n.failureMessage,r(o,{cmd:`xcrun`,args:a,stdout:s,stderr:c,deviceId:t.id,hint:G(s,c)??n.fallbackHint??`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`}))}return await V(i)}catch(r){throw r instanceof e?r:new e(`COMMAND_FAILED`,n.parseFailureMessage,{deviceId:t.id,cause:String(r)})}finally{await f.unlink(i).catch(()=>{})}}async function V(e){return JSON.parse(await f.readFile(e,`utf8`))}function H(e,t){return e.executable.slice(t.length+1).split(`/`).length}function Ge(e){return Array.isArray(e?.result?.runningProcesses)}function Ke(e){let t=e?.error?.userInfo?.NSUnderlyingError?.error;return t?.domain===`NSPOSIXErrorDomain`&&t.code===3}function qe(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||typeof e!=`object`)continue;let t=typeof e.bundleIdentifier==`string`?e.bundleIdentifier.trim():``;if(!t)continue;let r=typeof e.name==`string`&&e.name.trim().length>0?e.name.trim():t,i=typeof e.url==`string`&&e.url.trim().length>0?e.url.trim():void 0;n.push({bundleId:t,name:r,url:i})}return n}function Je(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||typeof e!=`object`)continue;let t=typeof e.executable==`string`?e.executable.trim():``,r=typeof e.processIdentifier==`number`&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;!t||!Number.isFinite(r)||n.push({executable:t,pid:r})}return n}function Ye(e,t){return ie(e,t)}const U=`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`,W=`This Xcode/CoreDevice toolchain must support 'devicectl device info processes' with JSON runningProcesses so agent-device can resolve app process IDs. Inspect diagnostics for the exact devicectl API failure.`;function G(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`device is busy`)&&n.includes(`connecting`)?`iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.`:n.includes(`coredeviceservice`)&&n.includes(`timed out`)?`CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.`:null}function K(e,t){return g(e,t)}function Xe(e,t,n){return l(K(e,t),n)}function q(e){return e.includes(`not installed`)||e.includes(`not found`)||e.includes(`no such file`)}async function Ze(e,t){return await R(e,t)}async function Qe(e,t){await L([`device`,`install`,`app`,`--device`,e.id,t],{action:`install iOS app`,deviceId:e.id},{timeoutMs:12e4})}async function $e(e,t){await L([`device`,`uninstall`,`app`,`--device`,e.id,t],{action:`uninstall iOS app ${t}`,deviceId:e.id},{tolerateOutput:(e,t)=>q(`${e}\n${t}`.toLowerCase())})}async function et(e,t){await We(e,t)}async function tt(e,t){return await z(e,t)}const J=1e4;async function nt(e,t,n={}){let r=[`device`,`process`,`launch`,`--device`,e.id,t];n.payloadUrl&&r.push(`--payload-url`,n.payloadUrl),n.launchArgs&&n.launchArgs.length>0&&r.push(`--`,...n.launchArgs),await L(r,{action:`launch iOS app`,deviceId:e.id})}async function rt(t){try{let{result:n,parsed:i}=await Y(t.id,15e3,3e3);if(n.exitCode===0){if(!i.parsed)throw new e(`COMMAND_FAILED`,`iOS device readiness probe failed`,{kind:`probe_inconclusive`,deviceId:t.id,stdout:n.stdout,stderr:n.stderr,hint:`CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device.`});let r=i.tunnelState?.toLowerCase();if(r===`connecting`)throw new e(`COMMAND_FAILED`,`iOS device is not ready for automation`,{kind:`not_ready`,deviceId:t.id,tunnelState:r,hint:`Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry.`});return}throw new e(`COMMAND_FAILED`,`iOS device is not ready for automation`,r(n,{kind:`not_ready`,deviceId:t.id,tunnelState:i.tunnelState,hint:Z(n.stdout,n.stderr)}))}catch(e){throw it(t.id,e)}}function it(t,n){return!(n instanceof e)||n.code!==`COMMAND_FAILED`?ot(t,n):(typeof n.details?.kind==`string`?n.details.kind:``)===`not_ready`?n:at(t,n)}function at(t,n){let r=n.details??{},i=String(r.stdout??``),a=String(r.stderr??``),o=Number(r.timeoutMs??15e3),s=`CoreDevice did not respond within ${o}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;return new e(`COMMAND_FAILED`,`iOS device readiness probe failed`,{deviceId:t,cause:n.message,timeoutMs:o,stdout:i,stderr:a,hint:i||a?Z(i,a):s},n)}function ot(t,n){return new e(`COMMAND_FAILED`,`iOS device readiness probe failed`,{deviceId:t,hint:`Reconnect the device, keep it unlocked, and retry.`},n instanceof Error?n:void 0)}async function st(e,t){if(typeof t==`number`&&t<=0)return null;let n=typeof t==`number`?Math.max(1,Math.min(J,t)):J;try{let t=await Y(e.id,n);return t.result.exitCode!==0||!t.parsed.parsed||t.parsed.outcome&&t.parsed.outcome!==`success`?null:t.parsed.tunnelIp??null}catch{return null}}async function Y(e,t,n=0){let r=m.join(p.tmpdir(),`agent-device-coredevice-info-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),i=Math.max(1,Math.ceil(t/1e3));try{return{result:await l([`devicectl`,`device`,`info`,`details`,`--device`,e,`--json-output`,r,`--timeout`,String(i)],{allowFailure:!0,timeoutMs:t+n}),parsed:await ct(r)}}finally{await f.rm(r,{force:!0}).catch(()=>{})}}async function ct(e){try{return{parsed:!0,...lt(JSON.parse(await f.readFile(e,`utf8`)))}}catch{return{parsed:!1}}}function lt(e){let t=e?.result;if(!t||typeof t!=`object`)return{};let n=t.connectionProperties,r=t.device?.connectionProperties,i=X(n?.tunnelState)??X(r?.tunnelState),a=X(n?.tunnelIPAddress)??X(r?.tunnelIPAddress),o=X(e?.info?.outcome);return{...o?{outcome:o}:{},...i?{tunnelState:i}:{},...a?{tunnelIp:a}:{}}}function X(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function Z(e,t){return G(e,t)||(`${e}\n${t}`.toLowerCase().includes(`timed out waiting for all destinations`)?`Xcode destination did not become available in time. Keep device unlocked and retry.`:U)}async function Q(t,n,r,i=I){let a=re.fromTimeoutMs(i),o={exitCode:1,stdout:``,stderr:``};for(let e of D)if(o=await l([`devicectl`,`device`,`copy`,`from`,`--device`,t.id,`--source`,n,`--destination`,r,`--domain-type`,`appDataContainer`,`--domain-identifier`,e],{allowFailure:!0,timeoutMs:ut(a,i)}),o.exitCode===0)return;throw new e(`COMMAND_FAILED`,`Failed to copy runner file from iOS device: ${o.stderr.trim()||o.stdout.trim()||`devicectl exited with code ${o.exitCode}`}`)}function ut(t,n){let r=t.remainingMs();if(r>0)return r;throw new e(`COMMAND_FAILED`,`iOS runner file copy timed out after ${n}ms`,{timeoutMs:n,step:`runner file copy`})}function $(t){if(!(t instanceof e))return{reason:t instanceof Error?t.message:String(t)};let n=t.details??{},r=Array.isArray(n.args)?n.args.filter(e=>typeof e==`string`).join(` `):void 0;return{errorCode:t.code,reason:t.message,timeoutMs:typeof n.timeoutMs==`number`?n.timeoutMs:void 0,exitCode:typeof n.exitCode==`number`?n.exitCode:void 0,stderr:typeof n.stderr==`string`&&n.stderr.trim()?n.stderr:void 0,stdout:typeof n.stdout==`string`&&n.stdout.trim()?n.stdout:void 0,commandArgs:r}}function dt(e){let t=e.details??{},n=typeof t.stdout==`string`?t.stdout:``,r=typeof t.stderr==`string`?t.stderr:``,i=Array.isArray(t.args)?t.args.filter(e=>typeof e==`string`).join(` `):``;return`${e.message}\n${n}\n${r}\n${i}`.toLowerCase()}async function ft(e,t,n){if(!n.preferRunner)try{await L([`device`,`screenshot`,`--device`,e.id,t],{action:`capture iOS screenshot`,deviceId:e.id});return}catch(t){if(!vt(t))throw t;_t(e,t)}let r=await mt(e,n,!1);await ht(r,t)||await Q(e,gt(r),t)}async function pt(t,n,r){if(!await ht(await mt(t,r,!0),n))throw new e(`COMMAND_FAILED`,`Failed to capture iOS screenshot: XCTest runner returned no inline image`,{deviceId:t.id,backend:`xctest`})}async function mt(e,t,n){return await t.runRunnerCommand(e,{command:`screenshot`,appBundleId:t.appBundleId,fullscreen:t.fullscreen,inlineScreenshot:n},t.runnerOptions??{})}async function ht(e,t){let n=e.imageBase64;return typeof n!=`string`||n.length===0?!1:(await f.writeFile(t,Buffer.from(n,`base64`)),!0)}function gt(t){let n=t.message;if(typeof n==`string`&&n.length>0)return n;throw new e(`COMMAND_FAILED`,`Failed to capture iOS screenshot: runner returned no file path`)}function _t(e,t){n({level:`warn`,phase:`ios_screenshot_fallback`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:`devicectl_screenshot`,to:`runner`,...$(t)}})}function vt(t){if(!(t instanceof e)||t.code!==`COMMAND_FAILED`)return!1;let n=dt(t);return n.includes(`unknown option '--device'`)||n.includes(`unknown subcommand`)&&n.includes(`screenshot`)||n.includes(`unrecognized subcommand`)&&n.includes(`screenshot`)}const yt={coredevice:{backend:`coredevice`,assertAppInstallationSupported:()=>{},ensureReady:rt,listApps:Ze,installApp:Qe,uninstallApp:$e,launchApp:nt,terminateApp:async(e,t)=>await et(e,t),resolveAppProcesses:tt,captureScreenshot:ft,copyRunnerFile:Q,resolveRunnerTransport:async(e,t)=>({kind:`network`,tunnelIp:await st(e,t)})},xctest:{backend:`xctest`,assertAppInstallationSupported:xt,ensureReady:Et,listApps:Ct,installApp:St,uninstallApp:St,launchApp:Dt,terminateApp:Ot,resolveAppProcesses:wt,captureScreenshot:pt,copyRunnerFile:Tt,resolveRunnerTransport:async()=>({kind:`usbmux`})}};function bt(e){return yt[e.iosPhysicalDeviceBackend===`xctest`?`xctest`:`coredevice`]}function xt(t){throw new e(`UNSUPPORTED_OPERATION`,`Installing apps is unavailable on this XCTest-backed physical iOS device.`,{deviceId:t.id,backend:`xctest`,hint:`Install the app with Xcode, then open it in agent-device by bundle ID.`})}async function St(e){return xt(e)}async function Ct(t){throw new e(`UNSUPPORTED_OPERATION`,`App inventory is unavailable on this XCTest-backed physical iOS device.`,{deviceId:t.id,backend:`xctest`,hint:`Use an installed app bundle ID when opening the device.`})}async function wt(t){throw new e(`UNSUPPORTED_OPERATION`,`Process lookup is unavailable on this XCTest-backed physical iOS device.`,{deviceId:t.id,backend:`xctest`,hint:`Use a CoreDevice-backed iOS device for performance sampling.`})}async function Tt(t){throw new e(`UNSUPPORTED_OPERATION`,`Runner file copy is unavailable on this XCTest-backed physical iOS device.`,{deviceId:t.id,backend:`xctest`})}async function Et(t){let n=[`xcdevice`,`wait`,`--both`,`--timeout=15`,t.id],i=await l(n,{allowFailure:!0,timeoutMs:18e3});if(i.exitCode!==0)throw new e(`COMMAND_FAILED`,`iOS device is not ready for XCTest automation`,r(i,{cmd:`xcrun`,args:n,deviceId:t.id,backend:`xctest`,hint:"Keep the device unlocked, trusted, connected, and visible in `xcrun xcdevice list`, then retry."}))}async function Dt(t,n,r){if(r.payloadUrl||r.launchArgs&&r.launchArgs.length>0)throw new e(`UNSUPPORTED_OPERATION`,`XCTest-backed physical iOS devices do not support deep links or launch arguments during open.`,{deviceId:t.id,backend:`xctest`,hint:`Open the installed app by bundle ID without a URL or --launch-args.`});await r.runRunnerCommand(t,{command:`activate`,appBundleId:n},r.runnerOptions??{})}async function Ot(e,t,n){await n.runRunnerCommand(e,{command:`terminate`,appBundleId:t},n.runnerOptions??{})}export{De as A,T as C,P as D,Me as E,ce as F,h as I,g as L,x as M,ue as N,F as O,le as P,ae as R,xe as S,we as T,ze as _,Xe as a,ve as b,G as c,I as d,Fe as f,Be as g,He as h,q as i,ge as j,M as k,Ie as l,Ve as m,dt as n,K as o,Le as p,$ as r,U as s,bt as t,Pe as u,Re as v,N as w,k as x,D as y};
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{c as t,g as n,o as r,s as i}from"./sdk-device.js";import{C as a,j as o,p as s}from"./sdk-android-adb.js";import{n as c,t as ee}from"./version.js";import{c as te,o as ne,s as re}from"./boot-diagnostics.js";import{a as l,s as ie}from"./tool-provider.js";import u from"node:path";import d from"node:crypto";import f,{promises as p}from"node:fs";import m from"node:os";function h(e,t={}){let n=ne(t.simulatorSetPath);return n?[`simctl`,`--set`,n,...e]:[`simctl`,...e]}function g(e,t){return!i(e)||e.kind!==`simulator`?[`simctl`,...t]:h(t,{simulatorSetPath:e.simulatorSetPath})}function ae(e,t,n){return l(g(e,t),n)}const _={iOS:{sdkName:{simulator:`iphonesimulator`,device:`iphoneos`},derivedBaseName:{simulator:`ios-simulator`,device:`ios-device`},xctestrunHints:{simulator:{preferred:[`iphonesimulator`],disallowed:[`iphoneos`,`appletvos`,`appletvsimulator`,`macos`]},device:{preferred:[`iphoneos`],disallowed:[`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]}}},tvOS:{sdkName:{simulator:`appletvsimulator`,device:`appletvos`},derivedBaseName:{simulator:`tvos-simulator`,device:`tvos-device`},xctestrunHints:{simulator:{preferred:[`appletvsimulator`],disallowed:[`appletvos`,`iphoneos`,`iphonesimulator`,`macos`]},device:{preferred:[`appletvos`],disallowed:[`appletvsimulator`,`iphoneos`,`iphonesimulator`,`macos`]}}},macOS:{sdkName:{simulator:`macosx`,device:`macosx`},derivedBaseName:{simulator:`macos`,device:`macos`},xctestrunHints:{simulator:{preferred:[`macos`],disallowed:[`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`]},device:{preferred:[`macos`],disallowed:[`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`]}}},visionOS:{sdkName:{simulator:`xrsimulator`,device:`xros`},derivedBaseName:{simulator:`visionos-simulator`,device:`visionos-device`},xctestrunHints:{simulator:{preferred:[`xrsimulator`],disallowed:[`xros`,`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]},device:{preferred:[`xros`],disallowed:[`xrsimulator`,`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]}}}};function v(i){if(!r(i.platform))throw new e(`UNSUPPORTED_PLATFORM`,`Unsupported platform for Apple runner: ${i.platform}`);return t(i)?`macOS`:n(i.target,i.appleOs)}function oe(e,t){return _[e].sdkName[y(t)]}function se(e){return _[v(e)].derivedBaseName[y(e.kind)]}function ce(e){return _[v(e)].xctestrunHints[y(e.kind)]}function le(e){let t=v(e);return t===`macOS`?`platform=macOS,arch=${b()}`:e.kind===`simulator`?`platform=${t} Simulator,id=${e.id}`:`platform=${t},id=${e.id}`}function ue(e){let t=v(e);return t===`macOS`?`platform=macOS,arch=${b()}`:e.kind===`simulator`?`platform=${t} Simulator,id=${e.id}`:`generic/platform=${t}`}function de(e){let t=v(e);return t===`macOS`?`platform=macOS,arch=${b()}`:e.kind===`simulator`?`generic/platform=${t} Simulator`:`generic/platform=${t}`}function y(e){return e===`simulator`?`simulator`:`device`}function b(){return process.arch===`arm64`?`arm64`:`x86_64`}const fe=new Set;function x(e={}){let t=new Map,n=e.now??(()=>Date.now()),r=e=>{e?.timer&&clearTimeout(e.timer)},i={get(e){let r=t.get(e);if(r){if(r.expiresAt!==void 0&&r.expiresAt<=n()){i.delete(e);return}return r.value}},set(i,a){r(t.get(i));let o=pe(e.ttlMs,n),s={value:a,expiresAt:o};e.scheduleExpiry&&o!==void 0&&(s.timer=setTimeout(()=>{t.delete(i)},Math.max(0,o-n())),s.timer.unref?.()),t.set(i,s)},delete(e){let n=t.get(e);return n?(r(n),t.delete(e)):!1},clear(){for(let e of t.values())r(e);t.clear()}};return fe.add(i.clear),i}function pe(e,t){if(!(e===void 0||!Number.isFinite(e)))return t()+Math.max(0,e)}const me=u.join(`apple`,`runner`,`AgentDeviceRunner`),he=u.join(`dist`,`apple`,`runner`,`AgentDeviceRunner`);function S(e){let t=u.join(e,me);return f.existsSync(t)?t:u.join(e,he)}function ge(e){return u.join(S(e),`AgentDeviceRunner.xcodeproj`)}const _e=u.join(m.homedir(),`.agent-device`,`apple-runner`),ve=`.agent-device-runner-cache.json`,ye=[`-IDEPackageSupportDisableManifestSandbox=1`,`-IDEPackageSupportDisablePluginExecutionSandbox=1`,`ENABLE_USER_SCRIPT_SANDBOXING=NO`],C=x();function w(e){return e?.trim()??``}function T(e=process.env){return w(e.AGENT_DEVICE_IOS_BUNDLE_ID)||w(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||`com.callstack.agentdevice.runner`}function E(e=process.env){return w(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID)||`${T(e)}.uitests`}function be(e=process.env){let t=T(e),n=E(e);return Array.from(new Set([w(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}const D=be(process.env);function xe(e,t=ee()){let n=v(e);return{schemaVersion:2,packageVersion:c(t),runnerSourceFingerprint:Oe(t),...Se(n,e.kind),platformName:n,deviceKind:e.kind,target:e.target??`mobile`,buildDestinationFamily:de(e),runnerBundleBuildSettings:N(process.env),runnerSigningBuildSettings:M(process.env,e.kind===`device`,e),runnerPerformanceBuildSettings:P(),runnerSandboxBuildArgs:F()}}function Se(e,t){let n=Ce(O(`xcodebuild`,[`-version`])),r=oe(e,t);return{xcodeVersion:n.version,xcodeBuildVersion:n.buildVersion,sdkName:r,sdkVersion:O(`xcrun`,[`--sdk`,r,`--show-sdk-version`]),sdkBuildVersion:O(`xcrun`,[`--sdk`,r,`--show-sdk-build-version`])}}function O(e,t){let n=JSON.stringify([e,t]),r=C.get(n);if(r!==void 0)return r;try{let r=a(e,t,{allowFailure:!0,timeoutMs:5e3,maxBuffer:128*1024}),i=r.exitCode===0&&r.stdout.trim()||`unknown`;return C.set(n,i),i}catch{return C.set(n,`unknown`),`unknown`}}function Ce(e){return{version:e.match(/^Xcode\s+(.+)$/m)?.[1]?.trim()||`unknown`,buildVersion:e.match(/^Build version\s+(.+)$/m)?.[1]?.trim()||`unknown`}}function we(e,t){let n=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim();if(n)return u.resolve(n);let r=Ee(t),i=Te(e);return u.join(i,r)}function Te(e){return u.join(_e,`derived`,se(e))}function Ee(e){return`cache-${d.createHash(`sha256`).update(De(k(e))).digest(`hex`).slice(0,16)}`}function k(e){let{artifacts:t,packageVersion:n,...r}=e;return r}function De(e){return JSON.stringify(A(e))}function A(e){return Array.isArray(e)?e.map(e=>A(e)):!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,A(t)]))}const j=new Map;function Oe(e){let t=S(e),n=Ae(t),r=ke(t,n),i=j.get(t);if(i?.fileStatsFingerprint===r)return i.sourceFingerprint;let a=d.createHash(`sha256`);for(let e of n){let n=u.relative(t,e);a.update(n),a.update(`\0`),a.update(f.readFileSync(e)),a.update(`\0`)}let o=a.digest(`hex`);return j.set(t,{fileStatsFingerprint:r,sourceFingerprint:o}),o}function ke(e,t){let n=d.createHash(`sha256`);for(let r of t){let t=u.relative(e,r),i=f.statSync(r);n.update(t),n.update(`\0`),n.update(String(i.size)),n.update(`\0`),n.update(String(Math.trunc(i.mtimeMs))),n.update(`\0`)}return n.digest(`hex`)}function Ae(e){if(!f.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of f.readdirSync(e,{withFileTypes:!0})){let i=u.join(e,r.name);if(r.isDirectory()){if(r.name===`xcuserdata`)continue;n.push(i);continue}r.isFile()&&je(r.name,i)&&t.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}function je(e,t){return e===`project.pbxproj`?t.includes(`${u.sep}.xcodeproj${u.sep}`):[`.jpg`,`.json`,`.png`,`.swift`,`.m`,`.h`,`.plist`,`.entitlements`,`.xctestplan`,`.xcconfig`,`.storyboard`,`.xib`].includes(u.extname(e))}function Me(e){return t(e)||e.kind===`device`?`-maximum-concurrent-test-device-destinations`:`-maximum-concurrent-test-simulator-destinations`}function M(e=process.env,n=!1,r={platform:`apple`}){if(t(r))return[`CODE_SIGNING_ALLOWED=NO`,`CODE_SIGNING_REQUIRED=NO`,`CODE_SIGN_IDENTITY=`,`DEVELOPMENT_TEAM=`];if(!n)return[];let i=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||``,a=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||``,o=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||``,s=[`CODE_SIGN_STYLE=Automatic`];return i&&s.push(`DEVELOPMENT_TEAM=${i}`),a&&s.push(`CODE_SIGN_IDENTITY=${a}`),o&&s.push(`PROVISIONING_PROFILE_SPECIFIER=${o}`),s}function N(e=process.env){let t=T(e),n=E(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}function P(){return[`COMPILER_INDEX_STORE_ENABLE=NO`,`ENABLE_CODE_COVERAGE=NO`,`ONLY_ACTIVE_ARCH=YES`,`ENABLE_PREVIEWS=NO`,`ENABLE_DEBUG_DYLIB=NO`]}function F(){return[...ye,`OTHER_SWIFT_FLAGS=${Ne(process.env)}`]}function Ne(e){return te(e.AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS)?`$(inherited) -disable-sandbox -D AGENT_DEVICE_RUNNER_UNIT_TESTS`:`$(inherited) -disable-sandbox`}const Pe=18e4,Fe=6e4,Ie=6e4,Le=1e4,Re=15e3,ze=2e4,Be=15e3,I=2e4,Ve=1e3,He=5e3;async function L(t,n,r={}){let i=[`devicectl`,...t],a=await l(i,{allowFailure:!0,timeoutMs:r.timeoutMs??2e4});if(a.exitCode===0)return;let{stdout:o,stderr:c}=a;if(!r.tolerateOutput?.(o,c))throw new e(`COMMAND_FAILED`,`Failed to ${n.action}`,s(a,{cmd:`xcrun`,args:i,stdout:o,stderr:c,deviceId:n.deviceId,hint:G(o,c)??`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`}))}async function R(e,t){return Ye(qe(await B(e,{jsonPrefix:`agent-device-ios-apps`,args:[`devicectl`,`device`,`info`,`apps`,`--device`,e.id,`--include-all-apps`],failureMessage:`Failed to list iOS apps`,parseFailureMessage:`Failed to parse iOS apps list`})),t)}async function Ue(t){let n=await B(t,{jsonPrefix:`agent-device-ios-processes`,args:[`devicectl`,`device`,`info`,`processes`,`--device`,t.id],failureMessage:`Failed to list iOS processes`,parseFailureMessage:`Failed to parse iOS process list`,fallbackHint:W});if(!Ge(n))throw new e(`COMMAND_FAILED`,`Unsupported iOS process list response`,{deviceId:t.id,hint:W});return Je(n)}async function We(e,t){let{appBundleUrl:n,processes:r}=await z(e,t),i=r.sort((e,t)=>H(e,n)-H(t,n))[0];i&&await B(e,{jsonPrefix:`agent-device-ios-process-terminate`,args:[`devicectl`,`device`,`process`,`terminate`,`--device`,e.id,`--pid`,String(i.pid),`--kill`],failureMessage:`Failed to terminate iOS app`,parseFailureMessage:`Failed to parse iOS process termination response`,tolerateFailurePayload:Ke})}async function z(t,n){let r=(await R(t,`all`)).find(e=>e.bundleId===n);if(!r)throw new e(`APP_NOT_INSTALLED`,`No iOS device app found for ${n}`,{appBundleId:n,deviceId:t.id});if(!r.url)throw new e(`COMMAND_FAILED`,`Missing app bundle URL for ${n}`,{appBundleId:n,deviceId:t.id,hint:`Installed-app metadata from devicectl did not include the bundle URL required to match running processes. Use an Xcode/CoreDevice toolchain that reports app URLs.`});let i=r.url.replace(/\/+$/,``);return{appBundleUrl:i,processes:(await Ue(t)).filter(e=>e.executable.startsWith(`${i}/`))}}async function B(t,n){let r=u.join(m.tmpdir(),`${n.jsonPrefix}-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),i=[...n.args,`--json-output`,r],a=await l(i,{allowFailure:!0,timeoutMs:2e4});try{if(a.exitCode!==0){let{stdout:o,stderr:c}=a;if(n.tolerateFailurePayload){let e=await V(r).catch(()=>void 0);if(e!==void 0&&n.tolerateFailurePayload(e))return e}throw new e(`COMMAND_FAILED`,n.failureMessage,s(a,{cmd:`xcrun`,args:i,stdout:o,stderr:c,deviceId:t.id,hint:G(o,c)??n.fallbackHint??`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`}))}return await V(r)}catch(r){throw r instanceof e?r:new e(`COMMAND_FAILED`,n.parseFailureMessage,{deviceId:t.id,cause:String(r)})}finally{await p.unlink(r).catch(()=>{})}}async function V(e){return JSON.parse(await p.readFile(e,`utf8`))}function H(e,t){return e.executable.slice(t.length+1).split(`/`).length}function Ge(e){return Array.isArray(e?.result?.runningProcesses)}function Ke(e){let t=e?.error?.userInfo?.NSUnderlyingError?.error;return t?.domain===`NSPOSIXErrorDomain`&&t.code===3}function qe(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||typeof e!=`object`)continue;let t=typeof e.bundleIdentifier==`string`?e.bundleIdentifier.trim():``;if(!t)continue;let r=typeof e.name==`string`&&e.name.trim().length>0?e.name.trim():t,i=typeof e.url==`string`&&e.url.trim().length>0?e.url.trim():void 0;n.push({bundleId:t,name:r,url:i})}return n}function Je(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||typeof e!=`object`)continue;let t=typeof e.executable==`string`?e.executable.trim():``,r=typeof e.processIdentifier==`number`&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;!t||!Number.isFinite(r)||n.push({executable:t,pid:r})}return n}function Ye(e,t){return ie(e,t)}const U=`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`,W=`This Xcode/CoreDevice toolchain must support 'devicectl device info processes' with JSON runningProcesses so agent-device can resolve app process IDs. Inspect diagnostics for the exact devicectl API failure.`;function G(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`device is busy`)&&n.includes(`connecting`)?`iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.`:n.includes(`coredeviceservice`)&&n.includes(`timed out`)?`CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.`:n.includes(`developer disk image`)||n.includes(`developer mode is disabled`)?`Enable Developer Mode on the iOS device (Settings > Privacy & Security > Developer Mode), restart it when prompted, unlock it, then retry.`:n.includes(`must be paired`)?`Pair the iOS device with this Mac: connect it by cable, unlock it, accept the Trust prompt, and enter the device passcode, then retry.`:null}function K(e,t){return g(e,t)}function Xe(e,t,n){return l(K(e,t),n)}function q(e){return e.includes(`not installed`)||e.includes(`not found`)||e.includes(`no such file`)}async function Ze(e,t){return await R(e,t)}async function Qe(e,t){await L([`device`,`install`,`app`,`--device`,e.id,t],{action:`install iOS app`,deviceId:e.id},{timeoutMs:12e4})}async function $e(e,t){await L([`device`,`uninstall`,`app`,`--device`,e.id,t],{action:`uninstall iOS app ${t}`,deviceId:e.id},{tolerateOutput:(e,t)=>q(`${e}\n${t}`.toLowerCase())})}async function et(e,t){await We(e,t)}async function tt(e,t){return await z(e,t)}const J=1e4;async function nt(e,t,n={}){let r=[`device`,`process`,`launch`,`--device`,e.id,t];n.payloadUrl&&r.push(`--payload-url`,n.payloadUrl),n.launchArgs&&n.launchArgs.length>0&&r.push(`--`,...n.launchArgs),await L(r,{action:`launch iOS app`,deviceId:e.id})}async function rt(t){try{let{result:n,parsed:r}=await Y(t.id,15e3,3e3);if(n.exitCode===0){if(!r.parsed)throw new e(`COMMAND_FAILED`,`iOS device readiness probe failed`,{kind:`probe_inconclusive`,deviceId:t.id,stdout:n.stdout,stderr:n.stderr,hint:`CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device.`});let i=r.tunnelState?.toLowerCase();if(i===`connecting`)throw new e(`COMMAND_FAILED`,`iOS device is not ready for automation`,{kind:`not_ready`,deviceId:t.id,tunnelState:i,hint:`Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry.`});return}throw new e(`COMMAND_FAILED`,`iOS device is not ready for automation`,s(n,{kind:`not_ready`,deviceId:t.id,tunnelState:r.tunnelState,hint:Z(n.stdout,n.stderr)}))}catch(e){throw it(t.id,e)}}function it(t,n){return!(n instanceof e)||n.code!==`COMMAND_FAILED`?ot(t,n):(typeof n.details?.kind==`string`?n.details.kind:``)===`not_ready`?n:at(t,n)}function at(t,n){let r=n.details??{},i=String(r.stdout??``),a=String(r.stderr??``),o=Number(r.timeoutMs??15e3),s=`CoreDevice did not respond within ${o}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;return new e(`COMMAND_FAILED`,`iOS device readiness probe failed`,{deviceId:t,cause:n.message,timeoutMs:o,stdout:i,stderr:a,hint:i||a?Z(i,a):s},n)}function ot(t,n){return new e(`COMMAND_FAILED`,`iOS device readiness probe failed`,{deviceId:t,hint:`Reconnect the device, keep it unlocked, and retry.`},n instanceof Error?n:void 0)}async function st(e,t){if(typeof t==`number`&&t<=0)return null;let n=typeof t==`number`?Math.max(1,Math.min(J,t)):J;try{let t=await Y(e.id,n);return t.result.exitCode!==0||!t.parsed.parsed||t.parsed.outcome&&t.parsed.outcome!==`success`?null:t.parsed.tunnelIp??null}catch{return null}}async function Y(e,t,n=0){let r=u.join(m.tmpdir(),`agent-device-coredevice-info-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),i=Math.max(1,Math.ceil(t/1e3));try{return{result:await l([`devicectl`,`device`,`info`,`details`,`--device`,e,`--json-output`,r,`--timeout`,String(i)],{allowFailure:!0,timeoutMs:t+n}),parsed:await ct(r)}}finally{await p.rm(r,{force:!0}).catch(()=>{})}}async function ct(e){try{return{parsed:!0,...lt(JSON.parse(await p.readFile(e,`utf8`)))}}catch{return{parsed:!1}}}function lt(e){let t=e?.result;if(!t||typeof t!=`object`)return{};let n=t.connectionProperties,r=t.device?.connectionProperties,i=X(n?.tunnelState)??X(r?.tunnelState),a=X(n?.tunnelIPAddress)??X(r?.tunnelIPAddress),o=X(e?.info?.outcome);return{...o?{outcome:o}:{},...i?{tunnelState:i}:{},...a?{tunnelIp:a}:{}}}function X(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function Z(e,t){return G(e,t)||(`${e}\n${t}`.toLowerCase().includes(`timed out waiting for all destinations`)?`Xcode destination did not become available in time. Keep device unlocked and retry.`:U)}async function Q(t,n,r,i=I){let a=re.fromTimeoutMs(i),o={exitCode:1,stdout:``,stderr:``};for(let e of D)if(o=await l([`devicectl`,`device`,`copy`,`from`,`--device`,t.id,`--source`,n,`--destination`,r,`--domain-type`,`appDataContainer`,`--domain-identifier`,e],{allowFailure:!0,timeoutMs:ut(a,i)}),o.exitCode===0)return;throw new e(`COMMAND_FAILED`,`Failed to copy runner file from iOS device: ${o.stderr.trim()||o.stdout.trim()||`devicectl exited with code ${o.exitCode}`}`)}function ut(t,n){let r=t.remainingMs();if(r>0)return r;throw new e(`COMMAND_FAILED`,`iOS runner file copy timed out after ${n}ms`,{timeoutMs:n,step:`runner file copy`})}function $(t){if(!(t instanceof e))return{reason:t instanceof Error?t.message:String(t)};let n=t.details??{},r=Array.isArray(n.args)?n.args.filter(e=>typeof e==`string`).join(` `):void 0;return{errorCode:t.code,reason:t.message,timeoutMs:typeof n.timeoutMs==`number`?n.timeoutMs:void 0,exitCode:typeof n.exitCode==`number`?n.exitCode:void 0,stderr:typeof n.stderr==`string`&&n.stderr.trim()?n.stderr:void 0,stdout:typeof n.stdout==`string`&&n.stdout.trim()?n.stdout:void 0,commandArgs:r}}function dt(e){let t=e.details??{},n=typeof t.stdout==`string`?t.stdout:``,r=typeof t.stderr==`string`?t.stderr:``,i=Array.isArray(t.args)?t.args.filter(e=>typeof e==`string`).join(` `):``;return`${e.message}\n${n}\n${r}\n${i}`.toLowerCase()}async function ft(e,t,n){if(!n.preferRunner)try{await L([`device`,`screenshot`,`--device`,e.id,t],{action:`capture iOS screenshot`,deviceId:e.id});return}catch(t){if(!vt(t))throw t;_t(e,t)}let r=await mt(e,n,!1);await ht(r,t)||await Q(e,gt(r),t)}async function pt(t,n,r){if(!await ht(await mt(t,r,!0),n))throw new e(`COMMAND_FAILED`,`Failed to capture iOS screenshot: XCTest runner returned no inline image`,{deviceId:t.id,backend:`xctest`})}async function mt(e,t,n){return await t.runRunnerCommand(e,{command:`screenshot`,appBundleId:t.appBundleId,fullscreen:t.fullscreen,inlineScreenshot:n},t.runnerOptions??{})}async function ht(e,t){let n=e.imageBase64;return typeof n!=`string`||n.length===0?!1:(await p.writeFile(t,Buffer.from(n,`base64`)),!0)}function gt(t){let n=t.message;if(typeof n==`string`&&n.length>0)return n;throw new e(`COMMAND_FAILED`,`Failed to capture iOS screenshot: runner returned no file path`)}function _t(e,t){o({level:`warn`,phase:`ios_screenshot_fallback`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:`devicectl_screenshot`,to:`runner`,...$(t)}})}function vt(t){if(!(t instanceof e)||t.code!==`COMMAND_FAILED`)return!1;let n=dt(t);return n.includes(`unknown option '--device'`)||n.includes(`unknown subcommand`)&&n.includes(`screenshot`)||n.includes(`unrecognized subcommand`)&&n.includes(`screenshot`)}const yt={coredevice:{backend:`coredevice`,assertAppInstallationSupported:()=>{},ensureReady:rt,listApps:Ze,installApp:Qe,uninstallApp:$e,launchApp:nt,terminateApp:async(e,t)=>await et(e,t),resolveAppProcesses:tt,captureScreenshot:ft,copyRunnerFile:Q,resolveTunnel:async(e,t)=>({tunnelIp:await st(e,t)})},xctest:{backend:`xctest`,assertAppInstallationSupported:xt,ensureReady:Dt,listApps:Ct,installApp:St,uninstallApp:St,launchApp:Ot,terminateApp:kt,resolveAppProcesses:wt,captureScreenshot:pt,copyRunnerFile:Et,resolveTunnel:Tt}};function bt(e){return yt[e.iosPhysicalDeviceBackend===`xctest`?`xctest`:`coredevice`]}function xt(t){throw new e(`UNSUPPORTED_OPERATION`,`Installing apps is unavailable on this XCTest-backed physical iOS device.`,{deviceId:t.id,backend:`xctest`,hint:`Install the app with Xcode, then open it in agent-device by bundle ID.`})}async function St(e){return xt(e)}async function Ct(t){throw new e(`UNSUPPORTED_OPERATION`,`App inventory is unavailable on this XCTest-backed physical iOS device.`,{deviceId:t.id,backend:`xctest`,hint:`Use an installed app bundle ID when opening the device.`})}async function wt(t){throw new e(`UNSUPPORTED_OPERATION`,`Process lookup is unavailable on this XCTest-backed physical iOS device.`,{deviceId:t.id,backend:`xctest`,hint:`Use a CoreDevice-backed iOS device for performance sampling.`})}async function Tt(t){throw new e(`UNSUPPORTED_OPERATION`,`XCTest-backed physical iOS devices have no CoreDevice tunnel.`,{deviceId:t.id,backend:`xctest`,hint:`Connect the device by cable so it is reachable through usbmux.`})}async function Et(t){throw new e(`UNSUPPORTED_OPERATION`,`Runner file copy is unavailable on this XCTest-backed physical iOS device.`,{deviceId:t.id,backend:`xctest`})}async function Dt(t){let n=[`xcdevice`,`wait`,`--both`,`--timeout=15`,t.id],r=await l(n,{allowFailure:!0,timeoutMs:18e3});if(r.exitCode!==0)throw new e(`COMMAND_FAILED`,`iOS device is not ready for XCTest automation`,s(r,{cmd:`xcrun`,args:n,deviceId:t.id,backend:`xctest`,hint:"Keep the device unlocked, trusted, connected, and visible in `xcrun xcdevice list`, then retry."}))}async function Ot(t,n,r){if(r.payloadUrl||r.launchArgs&&r.launchArgs.length>0)throw new e(`UNSUPPORTED_OPERATION`,`XCTest-backed physical iOS devices do not support deep links or launch arguments during open.`,{deviceId:t.id,backend:`xctest`,hint:`Open the installed app by bundle ID without a URL or --launch-args.`});await r.runRunnerCommand(t,{command:`activate`,appBundleId:n},r.runnerOptions??{})}async function kt(e,t,n){await n.runRunnerCommand(e,{command:`terminate`,appBundleId:t},n.runnerOptions??{})}export{De as A,T as C,P as D,Me as E,ce as F,h as I,g as L,x as M,ue as N,F as O,le as P,ae as R,xe as S,we as T,ze as _,Xe as a,ve as b,G as c,I as d,Fe as f,Be as g,He as h,q as i,ge as j,M as k,Ie as l,Ve as m,dt as n,K as o,Le as p,$ as r,U as s,bt as t,Pe as u,Re as v,N as w,k as x,D as y};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(t,n){for(let r of t){if(r.name===`dict`)for(let e=0;e<r.children.length-1;e+=1){let t=r.children[e],i=r.children[e+1];t?.name===`key`&&t.text&&i&&n(t.text,i)}e(r.children,n)}}export{e as t};
|