agent-device 0.20.1 → 0.20.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/README.md +0 -2
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.1.apk → agent-device-android-ime-helper-0.20.3.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.3.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.1.manifest.json → agent-device-android-ime-helper-0.20.3.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.1.apk → 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 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.1.manifest.json → agent-device-android-snapshot-helper-0.20.3.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +2 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +1 -35
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -208
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +184 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Orientation.swift +92 -0
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android-adb.d.ts +3 -26
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-helpers.js +1 -0
- package/dist/src/app-lifecycle.js +5 -5
- package/dist/src/app-log-request-scope.js +1 -1
- package/dist/src/app-resolution.js +1 -1
- package/dist/src/apps.js +5 -5
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +6 -6
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +14 -14
- package/dist/src/click-button.d.ts +5 -0
- package/dist/src/client-metro.js +1 -0
- package/dist/src/command-schema.js +3 -3
- package/dist/src/context.js +1 -1
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/device-input-state.d.ts +26 -0
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/device.js +9 -0
- package/dist/src/devices2.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/gesture-plan-types.js +1 -0
- package/dist/src/gesture-plan.js +1 -0
- package/dist/src/index.d.ts +1174 -1413
- package/dist/src/input-actions.js +4 -4
- package/dist/src/install-artifact.js +5 -1
- package/dist/src/install-artifact2.js +1 -0
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction.d.ts +3 -6
- 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 -22
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +437 -0
- package/dist/src/limrun.js +1 -0
- package/dist/src/linux.js +1 -1
- package/dist/src/logcat.js +1 -5
- package/dist/src/metro.d.ts +71 -2
- package/dist/src/metro.js +1 -1
- package/dist/src/metro2.js +1 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/physical-device-control.js +1 -0
- package/dist/src/plist.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/recording-export-quality.js +12 -13
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +18 -18
- package/dist/src/remote-config.d.ts +5 -2
- package/dist/src/remote-config.js +1 -1
- package/dist/src/remote-config2.js +1 -0
- package/dist/src/reporting.js +8 -8
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -2
- package/dist/src/runner-lease.js +1 -1
- package/dist/src/runtime-transport.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime2.js +1 -1
- package/dist/src/sdk-android-adb.d.ts +4 -2
- package/dist/src/sdk-batch-runner.d.ts +13 -3
- package/dist/src/sdk-batch-runner.js +1 -1
- package/dist/src/sdk-contracts.d.ts +28 -2
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-remote-config.d.ts +119 -4
- 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/server.js +2 -2
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +8 -8
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-diagnostics.js +4 -4
- package/dist/src/snapshot2.js +1 -1
- 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/tv-remote.d.ts +213 -0
- package/dist/src/xml.js +2 -0
- package/package.json +49 -30
- package/server.json +2 -2
- package/smithery.yaml +1 -1
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.1.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.1.apk.sha256 +0 -1
- package/dist/src/android-system-chrome.js +0 -1
- package/dist/src/client-metro-companion.js +0 -1
- package/dist/src/metro-types.d.ts +0 -52
- package/dist/src/project-runtime.js +0 -1
- package/dist/src/scoped-provider.js +0 -1
- package/dist/src/simctl.js +0 -1
- package/dist/src/snapshot-quality.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{T as e}from"./sdk-batch-runner.js";import{
|
|
1
|
+
import{T as e}from"./sdk-batch-runner.js";import{It as t}from"./recording-export-quality.js";function n(e){return t(e)}function r(t,r){let i=n(t),a=i.leaseId??r?.leaseId,o=i.tenantId??r?.tenantId,s=i.runId??r?.runId;if(!(!o||!s||!a))return e({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(t,r){let i=n(t),a=r?.lease??r?.deviceLease??void 0;return e({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(t){let n=t.meta,r=e({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{Bt as t,Ht as n,Lt as r,On as i,Pt as a}from"./recording-export-quality.js";import{n as o,r as s}from"./lease-context.js";import{on as c}from"./internal/daemon.js";async function l(e){let{req:a,sessionName:c,sessionStore:l,leaseRegistry:f,providerRuntimeIds:p,providerRuntimeRequiredIds:m,leaseLifecycleProvider:h,cloudArtifactProvider:g}=e,_=o(a);switch(a.command){case i.artifacts:return{ok:!0,data:await d(a,s(a,l.get(c)),g)};case`lease_allocate`:{u(_.leaseProvider,p,m);let e=f.allocateLease(r(_)),t;try{t=await h?.allocate?.(e,{req:a})}catch(t){throw f.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=f.heartbeatLease(t(_)),n=await h?.heartbeat?.(e,{req:a});return{ok:!0,data:{lease:e,...n?{provider:n}:{}}}}case`lease_release`:{let e=n(_),t=f.getLease(e),r=t?await h?.release?.(t,{req:a}):void 0;return{ok:!0,data:{released:f.releaseLease(e).released,...r?{provider:r}:{}}}}default:return null}}function u(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 d(e,t,n){let r=h(e.flags,`providerSessionId`);return f(t,r)?await p(t.tenantId):await m(t,r,n)}function f(e,t){return a(e)||!e.leaseProvider&&!t}async function p(e){let t=await c(e);return{source:`daemon`,status:`ready`,artifacts:t,...t.length===0?{message:`No daemon artifacts available.`}:{}}}async function m(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 h(e,t){let n=e?.[t];return typeof n==`string`&&n.length>0?n:void 0}export{l as handleLeaseCommands};
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
import { A as SnapshotNode, B as DeviceTarget, D as Rect, E as RawSnapshotNode, H as PlatformSelector, N as SnapshotState, R as DeviceInfo, T as Point, j as SnapshotOptions$1, k as SnapshotBackend, o as DaemonRequest, p as LeaseBackend } from "./sdk-contracts.js";
|
|
2
|
+
import { c as ScrollDirection, o as GesturePlan, r as AndroidAdbProvider } from "./sdk-android-adb.js";
|
|
3
|
+
import { t as AppsFilter } from "./sdk-app-inventory.js";
|
|
4
|
+
import { n as AndroidKeyboardState, t as AndroidKeyboardDismissResult } from "./device-input-state.js";
|
|
5
|
+
import { a as CloudArtifactProvider, f as SnapshotCaptureAnnotations, n as DeviceRotation, p as SessionSurface, s as BackMode, t as TvRemoteButton, u as SnapshotDiagnosticsSummary } from "./tv-remote.js";
|
|
6
|
+
import { t as ClickButton } from "./click-button.js";
|
|
7
|
+
import Limrun from "@limrun/api";
|
|
8
|
+
import "@limrun/api/instance-client";
|
|
9
|
+
import "@limrun/api/ios-client";
|
|
10
|
+
//#region src/platforms/permission-utils.d.ts
|
|
11
|
+
type SettingOptions = {
|
|
12
|
+
permissionTarget?: string;
|
|
13
|
+
permissionMode?: string;
|
|
14
|
+
latitude?: number;
|
|
15
|
+
longitude?: number;
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/backend.d.ts
|
|
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
|
|
30
|
+
type RunnerLogicalLeaseContext = {
|
|
31
|
+
leaseId?: string;
|
|
32
|
+
clientId?: string;
|
|
33
|
+
tenantId?: string;
|
|
34
|
+
runId?: string;
|
|
35
|
+
leaseProvider?: string;
|
|
36
|
+
deviceKey?: string;
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/contracts/interactor-types.d.ts
|
|
40
|
+
type RunnerContext = {
|
|
41
|
+
requestId?: string;
|
|
42
|
+
appBundleId?: string;
|
|
43
|
+
verbose?: boolean;
|
|
44
|
+
logPath?: string;
|
|
45
|
+
traceLogPath?: string;
|
|
46
|
+
iosXctestrunFile?: string;
|
|
47
|
+
iosXctestDerivedDataPath?: string;
|
|
48
|
+
iosXctestEnvDir?: string;
|
|
49
|
+
runnerLeaseContext?: RunnerLogicalLeaseContext;
|
|
50
|
+
};
|
|
51
|
+
type ScreenshotOptions = {
|
|
52
|
+
appBundleId?: string;
|
|
53
|
+
pixelDensity?: number;
|
|
54
|
+
fullscreen?: boolean;
|
|
55
|
+
normalizeStatusBar?: boolean;
|
|
56
|
+
stabilize?: boolean;
|
|
57
|
+
surface?: SessionSurface;
|
|
58
|
+
skipIosSimulatorBootCheck?: boolean;
|
|
59
|
+
captureBackend?: 'runner';
|
|
60
|
+
};
|
|
61
|
+
type ElementSelectorKey = 'id' | 'label' | 'text' | 'value';
|
|
62
|
+
type ElementSelectorTapOptions = {
|
|
63
|
+
key: ElementSelectorKey;
|
|
64
|
+
value: string;
|
|
65
|
+
allowNonHittableCoordinateFallback?: boolean;
|
|
66
|
+
expectedPoint?: Point;
|
|
67
|
+
};
|
|
68
|
+
type SnapshotOptions = SnapshotOptions$1 & {
|
|
69
|
+
appBundleId?: string;
|
|
70
|
+
includeRects?: boolean;
|
|
71
|
+
includeHiddenContentHints?: boolean;
|
|
72
|
+
surface?: SessionSurface;
|
|
73
|
+
};
|
|
74
|
+
type SnapshotResult = Omit<BackendSnapshotResult, 'backend' | 'nodes'> & {
|
|
75
|
+
nodes?: RawSnapshotNode[];
|
|
76
|
+
backend: Extract<SnapshotBackend, 'android' | 'xctest' | 'linux-atspi' | 'web'>;
|
|
77
|
+
};
|
|
78
|
+
type Interactor = {
|
|
79
|
+
open(app: string, options?: {
|
|
80
|
+
activity?: string;
|
|
81
|
+
appBundleId?: string;
|
|
82
|
+
launchConsole?: string;
|
|
83
|
+
launchArgs?: string[];
|
|
84
|
+
terminateRunningApp?: boolean;
|
|
85
|
+
url?: string;
|
|
86
|
+
}): Promise<void>;
|
|
87
|
+
openDevice(): Promise<void>;
|
|
88
|
+
close(app: string): Promise<void>;
|
|
89
|
+
tap(x: number, y: number): Promise<Record<string, unknown> | void>;
|
|
90
|
+
tapElementSelector?(selector: ElementSelectorTapOptions): Promise<Record<string, unknown> | void>;
|
|
91
|
+
doubleTap(x: number, y: number): Promise<Record<string, unknown> | void>;
|
|
92
|
+
longPress(x: number, y: number, durationMs?: number): Promise<Record<string, unknown> | void>;
|
|
93
|
+
focus(x: number, y: number): Promise<Record<string, unknown> | void>;
|
|
94
|
+
type(text: string, delayMs?: number): Promise<void>;
|
|
95
|
+
fillElementSelector?(selector: ElementSelectorTapOptions, text: string, delayMs?: number): Promise<Record<string, unknown> | void>;
|
|
96
|
+
fill(x: number, y: number, text: string, delayMs?: number): Promise<Record<string, unknown> | void>;
|
|
97
|
+
scroll(direction: ScrollDirection, options?: {
|
|
98
|
+
amount?: number;
|
|
99
|
+
pixels?: number;
|
|
100
|
+
durationMs?: number;
|
|
101
|
+
}): Promise<Record<string, unknown> | void>;
|
|
102
|
+
screenshot(outPath: string, options?: ScreenshotOptions): Promise<void>;
|
|
103
|
+
setViewport?(width: number, height: number): Promise<Record<string, unknown> | void>;
|
|
104
|
+
snapshot(options?: SnapshotOptions): Promise<SnapshotResult>;
|
|
105
|
+
gestureViewport?(): Promise<Rect>;
|
|
106
|
+
back(mode?: BackMode): Promise<void>;
|
|
107
|
+
home(): Promise<void>;
|
|
108
|
+
setOrientation(orientation: DeviceRotation): Promise<{
|
|
109
|
+
orientation?: DeviceRotation;
|
|
110
|
+
} | void>;
|
|
111
|
+
performGesture?(plan: GesturePlan): Promise<Record<string, unknown> | void>;
|
|
112
|
+
appSwitcher(): Promise<void>;
|
|
113
|
+
tvRemote(button: TvRemoteButton, durationMs?: number): Promise<void>;
|
|
114
|
+
readClipboard(): Promise<string>;
|
|
115
|
+
writeClipboard(text: string): Promise<void>;
|
|
116
|
+
setSetting(setting: string, state: string, appId?: string, options?: SettingOptions): Promise<Record<string, unknown> | void>;
|
|
117
|
+
};
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/contracts/device-inventory.d.ts
|
|
120
|
+
type DeviceInventoryRequest = {
|
|
121
|
+
platform?: PlatformSelector;
|
|
122
|
+
target?: DeviceTarget;
|
|
123
|
+
deviceName?: string;
|
|
124
|
+
udid?: string;
|
|
125
|
+
serial?: string;
|
|
126
|
+
leaseId?: string;
|
|
127
|
+
leaseProvider?: string;
|
|
128
|
+
deviceKey?: string;
|
|
129
|
+
clientId?: string;
|
|
130
|
+
iosSimulatorSetPath?: string;
|
|
131
|
+
androidSerialAllowlist?: string[];
|
|
132
|
+
};
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region src/contracts/device-provider.d.ts
|
|
135
|
+
type DeviceLease = {
|
|
136
|
+
leaseId: string;
|
|
137
|
+
tenantId: string;
|
|
138
|
+
runId: string;
|
|
139
|
+
backend: LeaseBackend;
|
|
140
|
+
leaseProvider?: string;
|
|
141
|
+
deviceKey?: string;
|
|
142
|
+
clientId?: string;
|
|
143
|
+
createdAt: number;
|
|
144
|
+
heartbeatAt: number;
|
|
145
|
+
expiresAt: number;
|
|
146
|
+
};
|
|
147
|
+
type LeaseLifecycleContext = {
|
|
148
|
+
req: DaemonRequest;
|
|
149
|
+
};
|
|
150
|
+
type LeaseLifecycleProvider = {
|
|
151
|
+
allocate?: (lease: DeviceLease, context?: LeaseLifecycleContext) => Promise<Record<string, unknown> | undefined>;
|
|
152
|
+
heartbeat?: (lease: DeviceLease, context?: LeaseLifecycleContext) => Promise<Record<string, unknown> | undefined>;
|
|
153
|
+
release?: (lease: DeviceLease, context?: LeaseLifecycleContext) => Promise<Record<string, unknown> | undefined>;
|
|
154
|
+
};
|
|
155
|
+
type DeviceInventoryProvider = (request: DeviceInventoryRequest) => Promise<DeviceInfo[] | null | undefined>;
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/utils/retry.d.ts
|
|
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
|
|
288
|
+
type ProviderDeviceInstallResult = {
|
|
289
|
+
bundleId?: string;
|
|
290
|
+
packageName?: string;
|
|
291
|
+
appName?: string;
|
|
292
|
+
launchTarget?: string;
|
|
293
|
+
};
|
|
294
|
+
type ProviderDeviceInstallOptions = {
|
|
295
|
+
relaunch?: boolean;
|
|
296
|
+
appIdentifierHint?: string;
|
|
297
|
+
packageNameHint?: string;
|
|
298
|
+
};
|
|
299
|
+
type ProviderDeviceRuntime = {
|
|
300
|
+
provider: string;
|
|
301
|
+
leaseLifecycle: LeaseLifecycleProvider;
|
|
302
|
+
recoverExpiredLease?: ProviderExpiredLeaseRecovery;
|
|
303
|
+
cloudArtifacts?: CloudArtifactProvider;
|
|
304
|
+
deviceInventoryProvider: DeviceInventoryProvider;
|
|
305
|
+
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
|
+
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
|
+
installApp?(device: DeviceInfo, app: string, appPath: string, options?: ProviderDeviceInstallOptions): Promise<ProviderDeviceInstallResult | undefined>;
|
|
322
|
+
installInstallablePath?(device: DeviceInfo, installablePath: string, options?: ProviderDeviceInstallOptions): Promise<ProviderDeviceInstallResult | undefined>;
|
|
323
|
+
configurePortReverse?(options: ProviderPortReverseOptions): Promise<Record<string, unknown> | undefined>;
|
|
324
|
+
shutdown(): Promise<void>;
|
|
325
|
+
};
|
|
326
|
+
type ProviderPortReverseOptions = {
|
|
327
|
+
leaseId: string;
|
|
328
|
+
provider?: string;
|
|
329
|
+
devicePort: number;
|
|
330
|
+
hostPort: number;
|
|
331
|
+
name: string;
|
|
332
|
+
};
|
|
333
|
+
type ProviderExpiredLeaseRecovery = (lease: DeviceLease) => Promise<void>;
|
|
334
|
+
//#endregion
|
|
335
|
+
//#region src/providers/limrun/ios.d.ts
|
|
336
|
+
type LimrunIosRemoteInstallOptions = {
|
|
337
|
+
md5?: string;
|
|
338
|
+
relaunch?: boolean;
|
|
339
|
+
appIdentifierHint?: string;
|
|
340
|
+
};
|
|
341
|
+
type LimrunIosRemoteInstallResult = {
|
|
342
|
+
appId?: string;
|
|
343
|
+
};
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region src/providers/limrun/device-session.d.ts
|
|
346
|
+
type LimrunRecordingQuality = 5 | 6 | 7 | 8 | 9 | 10;
|
|
347
|
+
type LimrunInstalledApp = {
|
|
348
|
+
id: string;
|
|
349
|
+
name?: string;
|
|
350
|
+
installType?: string;
|
|
351
|
+
};
|
|
352
|
+
type LimrunForegroundApp = {
|
|
353
|
+
appId?: string;
|
|
354
|
+
activity?: string;
|
|
355
|
+
};
|
|
356
|
+
type LimrunIosCommandResult = {
|
|
357
|
+
code: number;
|
|
358
|
+
stdout: string;
|
|
359
|
+
stderr: string;
|
|
360
|
+
};
|
|
361
|
+
type LimrunIosCommandExecution = {
|
|
362
|
+
on(event: 'line-stdout' | 'line-stderr', listener: (line: string) => void): LimrunIosCommandExecution;
|
|
363
|
+
on(event: 'exit', listener: (code: number) => void): LimrunIosCommandExecution;
|
|
364
|
+
on(event: 'error', listener: (error: Error) => void): LimrunIosCommandExecution;
|
|
365
|
+
off(event: 'line-stdout' | 'line-stderr', listener: (line: string) => void): LimrunIosCommandExecution;
|
|
366
|
+
off(event: 'exit', listener: (code: number) => void): LimrunIosCommandExecution;
|
|
367
|
+
off(event: 'error', listener: (error: Error) => void): LimrunIosCommandExecution;
|
|
368
|
+
wait(): Promise<LimrunIosCommandResult>;
|
|
369
|
+
stop(): void;
|
|
370
|
+
};
|
|
371
|
+
type LimrunDeviceSessionBase = {
|
|
372
|
+
readonly platform: 'android' | 'ios';
|
|
373
|
+
readonly device: DeviceInfo;
|
|
374
|
+
readonly interactor: Interactor;
|
|
375
|
+
listApps(filter?: AppsFilter): Promise<LimrunInstalledApp[]>;
|
|
376
|
+
pressKey(key: string, modifiers?: string[]): Promise<void>;
|
|
377
|
+
startRecording(options?: {
|
|
378
|
+
quality?: LimrunRecordingQuality;
|
|
379
|
+
}): Promise<void>;
|
|
380
|
+
stopRecording(options: {
|
|
381
|
+
outPath: string;
|
|
382
|
+
}): Promise<string>;
|
|
383
|
+
};
|
|
384
|
+
type LimrunAndroidDeviceSession = LimrunDeviceSessionBase & {
|
|
385
|
+
readonly platform: 'android';
|
|
386
|
+
readonly adb: AndroidAdbProvider;
|
|
387
|
+
getForegroundApp(): Promise<LimrunForegroundApp | undefined>;
|
|
388
|
+
getKeyboardState(): Promise<AndroidKeyboardState>;
|
|
389
|
+
dismissKeyboard(): Promise<AndroidKeyboardDismissResult>;
|
|
390
|
+
readLogs(lineLimit: number): Promise<string>;
|
|
391
|
+
installRemoteApp(url: string): Promise<void>;
|
|
392
|
+
};
|
|
393
|
+
type LimrunIosDeviceSession = LimrunDeviceSessionBase & {
|
|
394
|
+
readonly platform: 'ios';
|
|
395
|
+
readonly viewport: {
|
|
396
|
+
width: number;
|
|
397
|
+
height: number;
|
|
398
|
+
};
|
|
399
|
+
readLogs(appId: string, lineLimit: number): Promise<string>;
|
|
400
|
+
installRemoteApp(url: string, options?: LimrunIosRemoteInstallOptions): Promise<LimrunIosRemoteInstallResult>;
|
|
401
|
+
runSimctl(args: string[]): LimrunIosCommandExecution;
|
|
402
|
+
};
|
|
403
|
+
type LimrunDeviceSession = LimrunAndroidDeviceSession | LimrunIosDeviceSession;
|
|
404
|
+
//#endregion
|
|
405
|
+
//#region src/providers/limrun/runtime.d.ts
|
|
406
|
+
type LimrunRuntimeOptions = {
|
|
407
|
+
apiKey: string;
|
|
408
|
+
region?: string;
|
|
409
|
+
};
|
|
410
|
+
declare class LimrunRuntime implements ProviderDeviceRuntime {
|
|
411
|
+
private readonly limrun;
|
|
412
|
+
private readonly sessions;
|
|
413
|
+
private readonly options;
|
|
414
|
+
readonly provider = "limrun";
|
|
415
|
+
readonly leaseLifecycle: LeaseLifecycleProvider;
|
|
416
|
+
readonly recoverExpiredLease: ProviderExpiredLeaseRecovery;
|
|
417
|
+
readonly deviceInventoryProvider: DeviceInventoryProvider;
|
|
418
|
+
constructor(options: LimrunRuntimeOptions);
|
|
419
|
+
ownsDevice(device: DeviceInfo): boolean;
|
|
420
|
+
getInteractor(device: DeviceInfo): Interactor | undefined;
|
|
421
|
+
getDeviceSession(device: DeviceInfo): LimrunDeviceSession | undefined;
|
|
422
|
+
installApp(device: DeviceInfo, app: string, appPath: string, options?: ProviderDeviceInstallOptions): Promise<ProviderDeviceInstallResult | undefined>;
|
|
423
|
+
installInstallablePath(device: DeviceInfo, installablePath: string, options?: ProviderDeviceInstallOptions): Promise<ProviderDeviceInstallResult | undefined>;
|
|
424
|
+
configurePortReverse(options: ProviderPortReverseOptions): Promise<Record<string, unknown> | undefined>;
|
|
425
|
+
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
|
+
}
|
|
436
|
+
//#endregion
|
|
437
|
+
export { type AndroidAdbProvider, type AndroidKeyboardDismissResult, type AndroidKeyboardState, type LimrunAndroidDeviceSession, type LimrunDeviceSession, type LimrunForegroundApp, type LimrunInstalledApp, type LimrunIosCommandExecution, type LimrunIosCommandResult, type LimrunIosDeviceSession, type LimrunIosRemoteInstallOptions, type LimrunIosRemoteInstallResult, type LimrunRecordingQuality, LimrunRuntime, type LimrunRuntimeOptions };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./runtime2.js";export{e as LimrunRuntime};
|
package/dist/src/linux.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{I as t}from"./sdk-android-adb.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{I as t}from"./sdk-android-adb.js";import{n}from"./gesture-plan.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 t=>{if(t.topology===`two`)throw new e(`UNSUPPORTED_OPERATION`,`Multi-touch gestures are not supported on Linux`);let{start:r,end:i}=n(t);await f(r.x,r.y,i.x,i.y,t.durationMs)},screenshot:(e,t)=>b(e,t),snapshot:async e=>{let n=await t(`snapshot_capture`,async()=>await r(e?.surface),{backend:`linux-atspi`});return{nodes:n.nodes??[],truncated:n.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,5 +1 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{_ as t
|
|
2
|
-
`).map(e=>e.trim()).filter(e=>e.length>0);if(t.length!==0)return t.at(-1)===`OK`&&t.pop(),t.join(`
|
|
3
|
-
`).trim()||void 0}async function P(e,t=E){return c(`adb`,A(e,[`shell`,`getprop`,`sys.boot_completed`]),{allowFailure:!0,timeoutMs:t})}async function F(e,t){let n=t.replace(/_/g,` `).trim();if(!j(e))return n||e;let r=await R(e);return r?r.replace(/_/g,` `):n||e}async function I(e,t,r){try{return await r(`adb`,A(e,t),{allowFailure:!0,timeoutMs:1e4})}catch(e){if(L(n(e)))return;throw e}}function L(e){return e.code===`COMMAND_FAILED`&&typeof e.details?.timeoutMs==`number`}async function R(e,t=c){for(let n of[`ro.boot.qemu.avd_name`,`persist.sys.avd_name`]){let r=await I(e,[`shell`,`getprop`,n],t);if(!r)continue;let i=r.stdout.trim();if(r.exitCode===0&&i.length>0)return i}let n=await I(e,[`emu`,`avd`,`name`],t);if(!n)return;let r=N(n.stdout);if(n.exitCode===0&&r)return r}function z(e){let t=e.toLowerCase();return t.includes(`tv`)||t.includes(`leanback`)?`tv`:null}function B(e){return/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(e)}async function V(e,t){let n=k(await c(`adb`,A(e,[`shell`,`cmd`,`package`,`has-feature`,t]),{allowFailure:!0,timeoutMs:E})).toLowerCase();return n.includes(`true`)?!0:n.includes(`false`)?!1:null}async function H(e){return(await O(D,2,async t=>await V(e,t))).some(e=>e===!0)}async function U(e){return z(k(await c(`adb`,A(e,[`shell`,`getprop`,`ro.build.characteristics`]),{allowFailure:!0,timeoutMs:E})))===`tv`||await H(e)||B(k(await c(`adb`,A(e,[`shell`,`pm`,`list`,`features`]),{allowFailure:!0,timeoutMs:E})))?`tv`:`mobile`}async function W(e={}){if(await d(),!await l(`adb`))throw new t(`TOOL_MISSING`,`adb not found in PATH`);let n=e.serialAllowlist??h(void 0),r=await O((await K()).filter(e=>!n||n.has(e.serial)),3,async({serial:e,rawModel:t})=>{let[n,r,i]=await Promise.all([F(e,t),ae(e),U(e)]);return{platform:`android`,id:e,name:n,kind:j(e)?`emulator`:`device`,target:i,booted:r}});return[...r,...await X(r)]}function G(e){return e.split(`
|
|
4
|
-
`).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`List of devices`)).map(e=>e.split(/\s+/)).flatMap(e=>{let t=e[0];return t===void 0||e[1]!==`device`?[]:[{serial:t,rawModel:(e.find(e=>e.startsWith(`model:`))??``).replace(`model:`,``)}]})}async function K(){try{return G((await c(`adb`,[`devices`,`-l`],{timeoutMs:E})).stdout)}catch(e){throw o(e)}}function q(e){return e.split(`
|
|
5
|
-
`).map(e=>e.trim()).filter(e=>e.length>0)}function J(e,t){let n=e.find(e=>e===t);if(n)return n;let r=M(t);return e.find(e=>M(e)===r)}async function Y(){return q(i(await c(`emulator`,[`-list-avds`],{allowFailure:!0,timeoutMs:E}),`Failed to list Android emulator AVDs`,{hint:`Verify Android emulator tooling is installed and available in PATH.`}).stdout)}async function X(e){let t=await Y().catch(()=>[]),n=new Set(e.filter(e=>e.kind===`emulator`).map(e=>M(e.name)));return t.filter(e=>!n.has(M(e))).map(e=>({platform:`android`,id:e,name:e,kind:`emulator`,target:Z(e),booted:!1}))}function Z(e){return/\b(tv|television)\b/i.test(M(e))?`tv`:`mobile`}function ne(e,t,n){let r=M(t);return e.find(e=>e.platform!==`android`||e.kind!==`emulator`||n&&e.id!==n?!1:M(e.name)===r)}async function re(e){let n=Date.now(),r=Math.min(1e3,Math.max(50,Math.floor(e.timeoutMs/20)));for(;Date.now()-n<e.timeoutMs;){try{let t=await ie(e.avdName,e.serial);if(t)return{platform:`android`,id:t,name:e.avdName,kind:`emulator`,target:`mobile`,booted:!1}}catch{}await u(r)}throw new t(`COMMAND_FAILED`,`Android emulator did not appear in time`,{avdName:e.avdName,serial:e.serial,timeoutMs:e.timeoutMs,hint:`Check emulator logs and verify the AVD can start from command line.`})}async function ie(e,t){let n=M(e),r=(await K()).filter(e=>t&&e.serial!==t?!1:j(e.serial));for(let e of r)if(M(e.rawModel)===n||M(await F(e.serial,e.rawModel))===n)return e.serial}async function ae(e){try{return(await P(e)).stdout.trim()===`1`}catch{return!1}}async function oe(e){await d();let n=e.avdName.trim();if(!n)throw new t(`INVALID_ARGS`,`Android emulator boot requires a non-empty AVD name.`);let i=e.timeoutMs??12e4;if(!await l(`adb`))throw new t(`TOOL_MISSING`,`adb not found in PATH`);if(!await l(`emulator`))throw new t(`TOOL_MISSING`,`emulator not found in PATH`);let a=await Y(),o=J(a,n);if(!o)throw new t(`DEVICE_NOT_FOUND`,`No Android emulator AVD named ${e.avdName}`,{requestedAvdName:n,availableAvds:a,hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."});let s=Date.now(),c=ne(await W(),o,e.serial),u=c&&j(c.id)?c:void 0;if(!u){let t=[`-avd`,o];e.headless&&t.push(`-no-window`,`-no-audio`),r(`emulator`,t)}let f=u??await re({avdName:o,serial:e.serial,timeoutMs:i}),p=Date.now()-s,m=Math.max(1e3,i-p);await Q(f.id,m);let h=(await W()).find(e=>e.id===f.id);return h?{...h,name:o,booted:!0}:{...f,name:o,booted:!0}}async function Q(e,r=6e4){let i=r,a=ee.fromTimeoutMs(i),o=Math.min(1e3,Math.max(50,Math.floor(i/20))),s=Math.max(1,Math.ceil(i/o)),c,l=!1;try{await g(async({deadline:n})=>{if(n?.isExpired())throw l=!0,new t(`COMMAND_FAILED`,`Android boot deadline exceeded`,{serial:e,timeoutMs:r,elapsedMs:a.elapsedMs(),message:`timeout`});let o=Math.max(1e3,n?.remainingMs()??i),s=await P(e,Math.min(o,E));if(c=s,s.stdout.trim()!==`1`)throw new t(`COMMAND_FAILED`,`Android device is still booting`,{serial:e,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode})},{maxAttempts:s,baseDelayMs:o,maxDelayMs:o,jitter:0,shouldRetry:e=>{let t=_({error:e,stdout:c?.stdout,stderr:c?.stderr,context:{platform:`android`,phase:`boot`}});return t!==`ADB_TRANSPORT_UNAVAILABLE`&&t!==`ANDROID_BOOT_TIMEOUT`}},{deadline:a,phase:`boot`,classifyReason:e=>_({error:e,stdout:c?.stdout,stderr:c?.stderr,context:{platform:`android`,phase:`boot`}})})}catch(r){let o=n(r),s=c?.stdout,u=c?.stderr,d=c?.exitCode,f=_({error:r,stdout:s,stderr:u,context:{platform:`android`,phase:`boot`}});f===`BOOT_COMMAND_FAILED`&&o.message===`Android device is still booting`&&(f=`ANDROID_BOOT_TIMEOUT`);let p={serial:e,timeoutMs:i,elapsedMs:a.elapsedMs(),reason:f,hint:v(f),stdout:s,stderr:u,exitCode:d};throw l||f===`ANDROID_BOOT_TIMEOUT`?new t(`COMMAND_FAILED`,`Android device did not finish booting in time`,p):o.code===`TOOL_MISSING`?new t(`TOOL_MISSING`,o.message,{...p,...o.details??{}}):f===`ADB_TRANSPORT_UNAVAILABLE`?new t(`COMMAND_FAILED`,o.message,{...p,...o.details??{}}):new t(o.code,o.message,{...p,...o.details??{}},o.cause)}}async function se(e,t,n){return await s(e)(t,n)}function ce(e){return{platform:`android`,id:e,name:e,kind:e.startsWith(`emulator-`)?`emulator`:`device`,booted:!0}}function le(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`no shell command implementation`)||n.includes(`unknown command`)}var ue=e({prepareAndroidInstallArtifact:()=>$});async function $(e,t){let n=e.kind===`url`&&p(e.url),r=await m({source:e,isInstallablePath:(e,t)=>t.isFile()&&de(e),installableLabel:`Android installable (.apk or .aab)`,allowArchiveExtraction:e.kind!==`url`||n,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await fe(r.installablePath);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:e.packageName,cleanup:r.cleanup}}catch(e){throw await r.cleanup(),e}}function de(e){let t=y.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function fe(e){let t=y.extname(e).toLowerCase();return t!==`.apk`&&t!==`.aab`?{}:{packageName:await f(e)}}async function pe(e,t={}){let n=[`logcat`,`-d`,`-v`,`time`];t.lines!==void 0&&n.push(`-t`,String(Math.max(1,Math.floor(t.lines))));let r=await e(n,{allowFailure:!0,timeoutMs:t.timeoutMs,signal:t.signal});if(r.exitCode!==0)throw a(`Failed to capture Android logcat`,r);return r.stdout}function me(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{ce as a,T as c,b as d,x as f,$ as i,Q as l,me as n,le as o,te as p,ue as r,se as s,pe as t,S as u};
|
|
1
|
+
import{t as e}from"./rolldown-runtime.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/metro.d.ts
CHANGED
|
@@ -1,9 +1,39 @@
|
|
|
1
1
|
import { v as SessionRuntimeHints } from "./sdk-contracts.js";
|
|
2
|
-
import {
|
|
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;
|
|
5
5
|
declare function buildBundleUrl(baseUrl: string, platform: 'ios' | 'android', entryPath?: string): string;
|
|
6
6
|
//#endregion
|
|
7
|
+
//#region src/metro/metro-types.d.ts
|
|
8
|
+
/** Re-export of {@link SessionRuntimeHints} under the Metro-specific alias used by public API consumers. */
|
|
9
|
+
type MetroRuntimeHints = SessionRuntimeHints;
|
|
10
|
+
type MetroBridgeRuntimePayload = {
|
|
11
|
+
metro_host?: string;
|
|
12
|
+
metro_port?: number;
|
|
13
|
+
metro_bundle_url?: string;
|
|
14
|
+
launch_url?: string;
|
|
15
|
+
};
|
|
16
|
+
type MetroBridgeDescriptor = {
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
base_url: string;
|
|
19
|
+
status_url?: string;
|
|
20
|
+
bundle_url?: string;
|
|
21
|
+
ios_runtime: MetroBridgeRuntimePayload;
|
|
22
|
+
android_runtime: MetroBridgeRuntimePayload;
|
|
23
|
+
upstream: {
|
|
24
|
+
bundle_url?: string;
|
|
25
|
+
host?: string;
|
|
26
|
+
port?: number;
|
|
27
|
+
status_url?: string;
|
|
28
|
+
};
|
|
29
|
+
probe: {
|
|
30
|
+
reachable: boolean;
|
|
31
|
+
status_code: number;
|
|
32
|
+
latency_ms: number;
|
|
33
|
+
detail: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
7
37
|
//#region src/metro/metro.d.ts
|
|
8
38
|
declare function resolveRuntimeTransport(runtime: SessionRuntimeHints | undefined): {
|
|
9
39
|
host: string;
|
|
@@ -65,5 +95,44 @@ type MetroTunnelWebSocketCloseMessage = {
|
|
|
65
95
|
};
|
|
66
96
|
type MetroTunnelRequestMessage = MetroTunnelPingMessage | MetroTunnelHttpRequestMessage | MetroTunnelWebSocketOpenMessage | MetroTunnelWebSocketFrameMessage | MetroTunnelWebSocketCloseMessage;
|
|
67
97
|
type MetroTunnelResponseMessage = MetroTunnelPongMessage | MetroTunnelHttpResponseMessage | MetroTunnelHttpErrorMessage | MetroTunnelWebSocketOpenResultMessage | MetroTunnelWebSocketFrameMessage | MetroTunnelWebSocketCloseMessage;
|
|
98
|
+
type StopMetroTunnelOptions = {
|
|
99
|
+
projectRoot: string;
|
|
100
|
+
profileKey?: string;
|
|
101
|
+
consumerKey?: string;
|
|
102
|
+
};
|
|
103
|
+
declare function stopMetroTunnel(options: StopMetroTunnelOptions): Promise<void>;
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/metro/client-metro.d.ts
|
|
106
|
+
type EnvSource = NodeJS.ProcessEnv | Record<string, string | undefined>;
|
|
107
|
+
type PrepareMetroRuntimeOptions = {
|
|
108
|
+
projectRoot?: string;
|
|
109
|
+
kind?: MetroPrepareKind;
|
|
110
|
+
metroPort?: number | string;
|
|
111
|
+
listenHost?: string;
|
|
112
|
+
statusHost?: string;
|
|
113
|
+
publicBaseUrl?: string;
|
|
114
|
+
proxyBaseUrl?: string;
|
|
115
|
+
proxyBearerToken?: string;
|
|
116
|
+
bridgeScope?: MetroBridgeScope;
|
|
117
|
+
launchUrl?: string;
|
|
118
|
+
companionProfileKey?: string;
|
|
119
|
+
companionConsumerKey?: string;
|
|
120
|
+
startupTimeoutMs?: number | string;
|
|
121
|
+
probeTimeoutMs?: number | string;
|
|
122
|
+
reuseExisting?: boolean;
|
|
123
|
+
installDependenciesIfNeeded?: boolean;
|
|
124
|
+
runtimeFilePath?: string;
|
|
125
|
+
logPath?: string;
|
|
126
|
+
env?: EnvSource;
|
|
127
|
+
};
|
|
128
|
+
type ReloadMetroOptions = {
|
|
129
|
+
metroHost?: string;
|
|
130
|
+
metroPort?: number | string;
|
|
131
|
+
bundleUrl?: string;
|
|
132
|
+
runtime?: MetroRuntimeHints;
|
|
133
|
+
timeoutMs?: number | string;
|
|
134
|
+
};
|
|
135
|
+
declare function prepareMetroRuntime(input?: PrepareMetroRuntimeOptions): Promise<PrepareMetroRuntimeResult>;
|
|
136
|
+
declare function reloadMetro(input?: ReloadMetroOptions): Promise<ReloadMetroResult>;
|
|
68
137
|
//#endregion
|
|
69
|
-
export { type MetroBridgeDescriptor, type MetroTunnelRequestMessage, type MetroTunnelResponseMessage, buildBundleUrl, normalizeBaseUrl, resolveRuntimeTransport };
|
|
138
|
+
export { type MetroBridgeDescriptor, type MetroTunnelRequestMessage, type MetroTunnelResponseMessage, buildBundleUrl, normalizeBaseUrl, prepareMetroRuntime, reloadMetro, resolveRuntimeTransport, stopMetroTunnel };
|
package/dist/src/metro.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./url.js";import{t as n}from"./metro2.js";export{t as buildBundleUrl,e as normalizeBaseUrl,n as resolveRuntimeTransport};
|
|
1
|
+
import{n as e,t}from"./url.js";import{n,t as r}from"./client-metro.js";import{n as i,t as a}from"./metro2.js";export{t as buildBundleUrl,e as normalizeBaseUrl,r as prepareMetroRuntime,n as reloadMetro,a as resolveRuntimeTransport,i as stopMetroTunnel};
|
package/dist/src/metro2.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{r as e}from"./client-metro.js";import{t}from"./runtime-transport.js";function n(e){return t(e)}async function r(t){await e(t)}export{r as n,n as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{a as t}from"./install-artifact.js";async function n(n,i,a){let o=typeof a.action==`string`&&a.action.trim()?a.action.trim():`${i}.TEST_PUSH`,s=[`shell`,`am`,`broadcast`,`-a`,o,`-p`,i],c=typeof a.receiver==`string`?a.receiver.trim():``;c&&s.push(`-n`,c);let l=a.extras;if(l!==void 0&&(typeof l!=`object`||!l||Array.isArray(l)))throw new e(`INVALID_ARGS`,`Android push payload extras must be an object`);let u=l??{},d=0;for(let[e,t]of Object.entries(u))e&&(r(s,e,t),d+=1);return await t(n,s),{action:o,extrasCount:d}}function r(t,n,r){if(typeof r==`string`){t.push(`--es`,n,r);return}if(typeof r==`boolean`){t.push(`--ez`,n,r?`true`:`false`);return}if(typeof r==`number`&&Number.isFinite(r)){if(Number.isInteger(r)){t.push(`--ei`,n,String(r));return}t.push(`--ef`,n,String(r));return}throw new e(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${n}". Use string, boolean, or number.`)}export{n as pushAndroidNotification};
|