@arenahito/droid-webscr 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/android/droid-webscr-server-android.jar +0 -0
- package/dist/bin.d.ts +5 -17
- package/dist/bin.js +334 -207
- package/dist/bin.js.map +1 -1
- package/package.json +8 -11
- package/web/assets/disconnected-phone-WRg-ns9U.png +0 -0
- package/web/assets/index-B3WqGQL0.js +10 -0
- package/web/assets/index-CxnoJHDV.css +2 -0
- package/web/index.html +13 -0
- package/dist/index.d.ts +0 -43
- package/dist/index.js +0 -15705
- package/dist/index.js.map +0 -1
- package/dist/main.d.ts +0 -22
- package/dist/main.js +0 -16204
- package/dist/main.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -5,80 +5,80 @@ var __export = (target, all) => {
|
|
|
5
5
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
8
|
+
// src/bin.ts
|
|
9
|
+
import { dirname as dirname2 } from "path";
|
|
10
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
11
|
+
|
|
12
|
+
// ../agent/src/device-server/artifact.ts
|
|
13
|
+
import { access } from "fs/promises";
|
|
14
|
+
import { constants } from "fs";
|
|
15
|
+
import { dirname, join } from "path";
|
|
16
|
+
import { fileURLToPath } from "url";
|
|
17
|
+
var deviceServerArtifactFileName = "droid-webscr-server-android.jar";
|
|
18
|
+
var deviceServerArtifactRemotePath = "/data/local/tmp/droid-webscr-server.jar";
|
|
19
|
+
var defaultDeviceServerArtifact = {
|
|
20
|
+
localPath: `android/server/build/${deviceServerArtifactFileName}`,
|
|
21
|
+
remotePath: deviceServerArtifactRemotePath
|
|
22
|
+
};
|
|
23
|
+
async function resolveDeviceServerArtifact(moduleUrl = import.meta.url, startDirectory = dirname(fileURLToPath(moduleUrl))) {
|
|
24
|
+
const candidates = ancestorDirectories(startDirectory).flatMap((directory) => [
|
|
25
|
+
join(directory, "android", deviceServerArtifactFileName),
|
|
26
|
+
join(directory, "android", "server", "build", deviceServerArtifactFileName)
|
|
27
|
+
]);
|
|
28
|
+
const checks = await Promise.all(
|
|
29
|
+
candidates.map(async (candidate) => ({
|
|
30
|
+
candidate,
|
|
31
|
+
exists: await isReadableFile(candidate)
|
|
32
|
+
}))
|
|
33
|
+
);
|
|
34
|
+
for (const check2 of checks) {
|
|
35
|
+
if (check2.exists) {
|
|
36
|
+
return {
|
|
37
|
+
localPath: check2.candidate,
|
|
38
|
+
remotePath: deviceServerArtifactRemotePath
|
|
39
|
+
};
|
|
33
40
|
}
|
|
34
|
-
},
|
|
35
|
-
publishConfig: {
|
|
36
|
-
access: "public"
|
|
37
|
-
},
|
|
38
|
-
scripts: {
|
|
39
|
-
build: "tsup && node ../../tools/package-agent.mjs",
|
|
40
|
-
dev: "tsc -p tsconfig.build.json --watch",
|
|
41
|
-
lint: "oxlint --config ../../oxlint.json src",
|
|
42
|
-
test: "vitest run",
|
|
43
|
-
"type-check": "tsc -p tsconfig.json --noEmit"
|
|
44
|
-
},
|
|
45
|
-
dependencies: {
|
|
46
|
-
"@fastify/websocket": "11.2.0",
|
|
47
|
-
fastify: "5.8.5",
|
|
48
|
-
pino: "10.3.1"
|
|
49
|
-
},
|
|
50
|
-
devDependencies: {
|
|
51
|
-
"@types/ws": "8.18.1"
|
|
52
41
|
}
|
|
53
|
-
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Android server artifact was not found. Run pnpm android:build before starting droid-webscr.`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
function ancestorDirectories(startDirectory) {
|
|
47
|
+
const directories = [];
|
|
48
|
+
let current = startDirectory;
|
|
49
|
+
while (true) {
|
|
50
|
+
directories.push(current);
|
|
51
|
+
const parent = dirname(current);
|
|
52
|
+
if (parent === current) {
|
|
53
|
+
return directories;
|
|
54
|
+
}
|
|
55
|
+
current = parent;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function isReadableFile(path) {
|
|
59
|
+
try {
|
|
60
|
+
await access(path, constants.R_OK);
|
|
61
|
+
return true;
|
|
62
|
+
} catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
54
66
|
|
|
55
|
-
// ../../packages/adb/
|
|
67
|
+
// ../../packages/adb/src/provider.ts
|
|
56
68
|
import { Readable } from "stream";
|
|
57
|
-
var AdbAuthorizationState;
|
|
58
|
-
(function(AdbAuthorizationState2) {
|
|
59
|
-
AdbAuthorizationState2["Authorized"] = "authorized";
|
|
60
|
-
AdbAuthorizationState2["Offline"] = "offline";
|
|
61
|
-
AdbAuthorizationState2["Unauthorized"] = "unauthorized";
|
|
62
|
-
})(AdbAuthorizationState || (AdbAuthorizationState = {}));
|
|
63
|
-
var AdbTransportKind;
|
|
64
|
-
(function(AdbTransportKind2) {
|
|
65
|
-
AdbTransportKind2["Emulator"] = "emulator";
|
|
66
|
-
AdbTransportKind2["Network"] = "network";
|
|
67
|
-
AdbTransportKind2["Usb"] = "usb";
|
|
68
|
-
})(AdbTransportKind || (AdbTransportKind = {}));
|
|
69
69
|
function isUsableDevice(device) {
|
|
70
|
-
return device.authorizationState ===
|
|
70
|
+
return device.authorizationState === "authorized" /* Authorized */ && device.serial.length > 0;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
// ../../packages/adb/
|
|
73
|
+
// ../../packages/adb/src/system-adb-provider.ts
|
|
74
74
|
import { spawn } from "child_process";
|
|
75
75
|
import { createConnection, Server } from "net";
|
|
76
76
|
import { Readable as Readable2 } from "stream";
|
|
77
77
|
var SystemAdbProvider = class _SystemAdbProvider {
|
|
78
|
-
adbPath;
|
|
79
78
|
constructor(adbPath = "adb") {
|
|
80
79
|
this.adbPath = adbPath;
|
|
81
80
|
}
|
|
81
|
+
adbPath;
|
|
82
82
|
/* v8 ignore next 4 -- external adb process boundary; deterministic parsing is unit-tested */
|
|
83
83
|
async listDevices() {
|
|
84
84
|
const output = await runAndCollect(this.adbPath, ["devices", "-l"]);
|
|
@@ -117,16 +117,16 @@ var SystemAdbProvider = class _SystemAdbProvider {
|
|
|
117
117
|
}
|
|
118
118
|
};
|
|
119
119
|
var SystemAdbDeviceSession = class {
|
|
120
|
+
constructor(adbPath, serial) {
|
|
121
|
+
this.adbPath = adbPath;
|
|
122
|
+
this.serial = serial;
|
|
123
|
+
}
|
|
120
124
|
adbPath;
|
|
121
125
|
serial;
|
|
122
126
|
forwards = /* @__PURE__ */ new Set();
|
|
123
127
|
sockets = /* @__PURE__ */ new Set();
|
|
124
128
|
shellChildren = /* @__PURE__ */ new Set();
|
|
125
129
|
shellCloses = /* @__PURE__ */ new Map();
|
|
126
|
-
constructor(adbPath, serial) {
|
|
127
|
-
this.adbPath = adbPath;
|
|
128
|
-
this.serial = serial;
|
|
129
|
-
}
|
|
130
130
|
async push(localPath, remotePath) {
|
|
131
131
|
await runAndCollect(this.adbPath, ["-s", this.serial, "push", localPath, remotePath]);
|
|
132
132
|
}
|
|
@@ -172,10 +172,16 @@ var SystemAdbDeviceSession = class {
|
|
|
172
172
|
this.forwards.add(forward.local);
|
|
173
173
|
try {
|
|
174
174
|
const socket = await connectLocalPortWithRetry(localPort);
|
|
175
|
-
const forwardedSocket = new ForwardedAdbSocket(
|
|
176
|
-
this.
|
|
177
|
-
this.
|
|
178
|
-
|
|
175
|
+
const forwardedSocket = new ForwardedAdbSocket(
|
|
176
|
+
this.adbPath,
|
|
177
|
+
this.serial,
|
|
178
|
+
forward.local,
|
|
179
|
+
socket,
|
|
180
|
+
() => {
|
|
181
|
+
this.forwards.delete(forward.local);
|
|
182
|
+
this.sockets.delete(forwardedSocket);
|
|
183
|
+
}
|
|
184
|
+
);
|
|
179
185
|
this.sockets.add(forwardedSocket);
|
|
180
186
|
return forwardedSocket;
|
|
181
187
|
} catch (error51) {
|
|
@@ -191,7 +197,9 @@ var SystemAdbDeviceSession = class {
|
|
|
191
197
|
await Promise.allSettled([
|
|
192
198
|
...this.shellCloses.values(),
|
|
193
199
|
...[...this.sockets].map((socket) => socket.close()),
|
|
194
|
-
...[...this.forwards].map(
|
|
200
|
+
...[...this.forwards].map(
|
|
201
|
+
(forward) => runAndCollect(this.adbPath, ["-s", this.serial, "forward", "--remove", forward])
|
|
202
|
+
)
|
|
195
203
|
]);
|
|
196
204
|
this.forwards.clear();
|
|
197
205
|
}
|
|
@@ -220,24 +228,24 @@ function parseDeviceLine(line) {
|
|
|
220
228
|
}
|
|
221
229
|
function parseAuthorizationState(state) {
|
|
222
230
|
if (state === "device") {
|
|
223
|
-
return
|
|
231
|
+
return "authorized" /* Authorized */;
|
|
224
232
|
}
|
|
225
233
|
if (state === "unauthorized") {
|
|
226
|
-
return
|
|
234
|
+
return "unauthorized" /* Unauthorized */;
|
|
227
235
|
}
|
|
228
|
-
return
|
|
236
|
+
return "offline" /* Offline */;
|
|
229
237
|
}
|
|
230
238
|
function inferTransportKind(serial, fields) {
|
|
231
239
|
if (serial.startsWith("emulator-")) {
|
|
232
|
-
return
|
|
240
|
+
return "emulator" /* Emulator */;
|
|
233
241
|
}
|
|
234
242
|
if (serial.includes(":")) {
|
|
235
|
-
return
|
|
243
|
+
return "network" /* Network */;
|
|
236
244
|
}
|
|
237
245
|
if (fields.some((field) => field.startsWith("usb:"))) {
|
|
238
|
-
return
|
|
246
|
+
return "usb" /* Usb */;
|
|
239
247
|
}
|
|
240
|
-
return
|
|
248
|
+
return "usb" /* Usb */;
|
|
241
249
|
}
|
|
242
250
|
function parseField(fields, key) {
|
|
243
251
|
const prefix = `${key}:`;
|
|
@@ -260,7 +268,9 @@ async function runAndCollect(command, args) {
|
|
|
260
268
|
return stdout;
|
|
261
269
|
}
|
|
262
270
|
async function startLogcatTail(command, serial) {
|
|
263
|
-
const epoch = Number(
|
|
271
|
+
const epoch = Number(
|
|
272
|
+
(await runAndCollect(command, ["-s", serial, "shell", "date", "+%s"])).trim()
|
|
273
|
+
);
|
|
264
274
|
if (!Number.isFinite(epoch)) {
|
|
265
275
|
throw new Error("Failed to read device logcat start time.");
|
|
266
276
|
}
|
|
@@ -369,12 +379,6 @@ function delay(ms) {
|
|
|
369
379
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
370
380
|
}
|
|
371
381
|
var ForwardedAdbSocket = class {
|
|
372
|
-
adbPath;
|
|
373
|
-
serial;
|
|
374
|
-
localForward;
|
|
375
|
-
socket;
|
|
376
|
-
onClose;
|
|
377
|
-
chunks;
|
|
378
382
|
constructor(adbPath, serial, localForward, socket, onClose = () => {
|
|
379
383
|
}) {
|
|
380
384
|
this.adbPath = adbPath;
|
|
@@ -384,6 +388,12 @@ var ForwardedAdbSocket = class {
|
|
|
384
388
|
this.onClose = onClose;
|
|
385
389
|
this.chunks = socket;
|
|
386
390
|
}
|
|
391
|
+
adbPath;
|
|
392
|
+
serial;
|
|
393
|
+
localForward;
|
|
394
|
+
socket;
|
|
395
|
+
onClose;
|
|
396
|
+
chunks;
|
|
387
397
|
async write(chunk) {
|
|
388
398
|
await new Promise((resolve, reject) => {
|
|
389
399
|
this.socket.write(chunk, (error51) => {
|
|
@@ -411,7 +421,7 @@ var ForwardedAdbSocket = class {
|
|
|
411
421
|
}
|
|
412
422
|
};
|
|
413
423
|
|
|
414
|
-
// ../../packages/shared/
|
|
424
|
+
// ../../packages/shared/src/index.ts
|
|
415
425
|
var AppError = class extends Error {
|
|
416
426
|
code;
|
|
417
427
|
constructor(code, message) {
|
|
@@ -14941,7 +14951,7 @@ function date4(params) {
|
|
|
14941
14951
|
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
14942
14952
|
config(en_default());
|
|
14943
14953
|
|
|
14944
|
-
// ../../packages/config/
|
|
14954
|
+
// ../../packages/config/src/schema.ts
|
|
14945
14955
|
var defaultAgentConfig = {
|
|
14946
14956
|
authToken: void 0,
|
|
14947
14957
|
bindHost: "127.0.0.1",
|
|
@@ -14964,7 +14974,9 @@ function validateAgentConfig(input) {
|
|
|
14964
14974
|
return err(new ConfigError("CONFIG_INVALID", parsed.error.message));
|
|
14965
14975
|
}
|
|
14966
14976
|
if (!isLocalBind(parsed.data.bindHost) && !parsed.data.authToken) {
|
|
14967
|
-
return err(
|
|
14977
|
+
return err(
|
|
14978
|
+
new ConfigError("CONFIG_UNSAFE_BIND", "Non-local bind addresses require authToken.")
|
|
14979
|
+
);
|
|
14968
14980
|
}
|
|
14969
14981
|
return ok(parsed.data);
|
|
14970
14982
|
}
|
|
@@ -14972,70 +14984,15 @@ function isLocalBind(host) {
|
|
|
14972
14984
|
return host === "127.0.0.1" || host === "localhost" || host === "::1";
|
|
14973
14985
|
}
|
|
14974
14986
|
|
|
14975
|
-
// src/runtime.ts
|
|
14987
|
+
// ../agent/src/runtime.ts
|
|
14976
14988
|
import { pathToFileURL } from "url";
|
|
14977
14989
|
|
|
14978
|
-
// src/device-server/
|
|
14979
|
-
import { access } from "fs/promises";
|
|
14980
|
-
import { constants } from "fs";
|
|
14981
|
-
import { dirname, join } from "path";
|
|
14982
|
-
import { fileURLToPath } from "url";
|
|
14983
|
-
var deviceServerArtifactFileName = "droid-webscr-server-android.jar";
|
|
14984
|
-
var deviceServerArtifactRemotePath = "/data/local/tmp/droid-webscr-server.jar";
|
|
14985
|
-
var defaultDeviceServerArtifact = {
|
|
14986
|
-
localPath: `android/server/build/${deviceServerArtifactFileName}`,
|
|
14987
|
-
remotePath: deviceServerArtifactRemotePath
|
|
14988
|
-
};
|
|
14989
|
-
async function resolveDeviceServerArtifact(moduleUrl = import.meta.url, startDirectory = dirname(fileURLToPath(moduleUrl))) {
|
|
14990
|
-
const candidates = ancestorDirectories(startDirectory).flatMap((directory) => [
|
|
14991
|
-
join(directory, "android", deviceServerArtifactFileName),
|
|
14992
|
-
join(directory, "android", "server", "build", deviceServerArtifactFileName)
|
|
14993
|
-
]);
|
|
14994
|
-
const checks = await Promise.all(
|
|
14995
|
-
candidates.map(async (candidate) => ({
|
|
14996
|
-
candidate,
|
|
14997
|
-
exists: await isReadableFile(candidate)
|
|
14998
|
-
}))
|
|
14999
|
-
);
|
|
15000
|
-
for (const check2 of checks) {
|
|
15001
|
-
if (check2.exists) {
|
|
15002
|
-
return {
|
|
15003
|
-
localPath: check2.candidate,
|
|
15004
|
-
remotePath: deviceServerArtifactRemotePath
|
|
15005
|
-
};
|
|
15006
|
-
}
|
|
15007
|
-
}
|
|
15008
|
-
throw new Error(
|
|
15009
|
-
`Android server artifact was not found. Run pnpm android:build before starting droid-webscr.`
|
|
15010
|
-
);
|
|
15011
|
-
}
|
|
15012
|
-
function ancestorDirectories(startDirectory) {
|
|
15013
|
-
const directories = [];
|
|
15014
|
-
let current = startDirectory;
|
|
15015
|
-
while (true) {
|
|
15016
|
-
directories.push(current);
|
|
15017
|
-
const parent = dirname(current);
|
|
15018
|
-
if (parent === current) {
|
|
15019
|
-
return directories;
|
|
15020
|
-
}
|
|
15021
|
-
current = parent;
|
|
15022
|
-
}
|
|
15023
|
-
}
|
|
15024
|
-
async function isReadableFile(path) {
|
|
15025
|
-
try {
|
|
15026
|
-
await access(path, constants.R_OK);
|
|
15027
|
-
return true;
|
|
15028
|
-
} catch {
|
|
15029
|
-
return false;
|
|
15030
|
-
}
|
|
15031
|
-
}
|
|
15032
|
-
|
|
15033
|
-
// src/device-server/deploy.ts
|
|
14990
|
+
// ../agent/src/device-server/deploy.ts
|
|
15034
14991
|
async function deployDeviceServer(session, artifact) {
|
|
15035
14992
|
await session.push(artifact.localPath, artifact.remotePath);
|
|
15036
14993
|
}
|
|
15037
14994
|
|
|
15038
|
-
// src/device-server/start.ts
|
|
14995
|
+
// ../agent/src/device-server/start.ts
|
|
15039
14996
|
var AdbDeviceServer = class {
|
|
15040
14997
|
constructor(adbProvider, artifact = defaultDeviceServerArtifact) {
|
|
15041
14998
|
this.adbProvider = adbProvider;
|
|
@@ -15193,36 +15150,30 @@ async function collectTextUntil(chunks, expected) {
|
|
|
15193
15150
|
return output + decoder.decode();
|
|
15194
15151
|
}
|
|
15195
15152
|
|
|
15196
|
-
// src/server/create-fastify-app.ts
|
|
15153
|
+
// ../agent/src/server/create-fastify-app.ts
|
|
15197
15154
|
import websocket from "@fastify/websocket";
|
|
15155
|
+
import middie from "@fastify/middie";
|
|
15198
15156
|
|
|
15199
|
-
// ../../packages/protocol/
|
|
15200
|
-
var StreamId
|
|
15201
|
-
(function(StreamId2) {
|
|
15157
|
+
// ../../packages/protocol/src/streams.ts
|
|
15158
|
+
var StreamId = /* @__PURE__ */ ((StreamId2) => {
|
|
15202
15159
|
StreamId2[StreamId2["Session"] = 1] = "Session";
|
|
15203
15160
|
StreamId2[StreamId2["Device"] = 2] = "Device";
|
|
15204
15161
|
StreamId2[StreamId2["Video"] = 3] = "Video";
|
|
15205
15162
|
StreamId2[StreamId2["Control"] = 4] = "Control";
|
|
15206
15163
|
StreamId2[StreamId2["Log"] = 5] = "Log";
|
|
15207
|
-
|
|
15208
|
-
|
|
15164
|
+
return StreamId2;
|
|
15165
|
+
})(StreamId || {});
|
|
15166
|
+
var knownStreams = new Set(
|
|
15167
|
+
Object.values(StreamId).filter((value) => typeof value === "number")
|
|
15168
|
+
);
|
|
15209
15169
|
|
|
15210
|
-
// ../../packages/protocol/
|
|
15170
|
+
// ../../packages/protocol/src/frame.ts
|
|
15211
15171
|
var FRAME_MAGIC = 1146573635;
|
|
15212
15172
|
var FRAME_HEADER_LENGTH = 40;
|
|
15213
15173
|
var WIRE_VERSION = 1;
|
|
15214
15174
|
var DEFAULT_MAX_PAYLOAD_LENGTH = 16 * 1024 * 1024;
|
|
15215
15175
|
|
|
15216
|
-
// ../../packages/protocol/
|
|
15217
|
-
var ProtocolErrorCode;
|
|
15218
|
-
(function(ProtocolErrorCode2) {
|
|
15219
|
-
ProtocolErrorCode2["FrameTooShort"] = "FRAME_TOO_SHORT";
|
|
15220
|
-
ProtocolErrorCode2["InvalidMagic"] = "INVALID_MAGIC";
|
|
15221
|
-
ProtocolErrorCode2["UnsupportedVersion"] = "UNSUPPORTED_VERSION";
|
|
15222
|
-
ProtocolErrorCode2["UnsupportedHeaderLength"] = "UNSUPPORTED_HEADER_LENGTH";
|
|
15223
|
-
ProtocolErrorCode2["PayloadLengthMismatch"] = "PAYLOAD_LENGTH_MISMATCH";
|
|
15224
|
-
ProtocolErrorCode2["PayloadTooLarge"] = "PAYLOAD_TOO_LARGE";
|
|
15225
|
-
})(ProtocolErrorCode || (ProtocolErrorCode = {}));
|
|
15176
|
+
// ../../packages/protocol/src/errors.ts
|
|
15226
15177
|
var ProtocolError = class extends Error {
|
|
15227
15178
|
code;
|
|
15228
15179
|
constructor(code, message) {
|
|
@@ -15232,7 +15183,7 @@ var ProtocolError = class extends Error {
|
|
|
15232
15183
|
}
|
|
15233
15184
|
};
|
|
15234
15185
|
|
|
15235
|
-
// ../../packages/protocol/
|
|
15186
|
+
// ../../packages/protocol/src/codec.ts
|
|
15236
15187
|
function encodeFrame(frame) {
|
|
15237
15188
|
const payloadLength = frame.payload.byteLength;
|
|
15238
15189
|
const output = new Uint8Array(FRAME_HEADER_LENGTH + payloadLength);
|
|
@@ -15253,28 +15204,37 @@ function encodeFrame(frame) {
|
|
|
15253
15204
|
function decodeFrame(bytes, options = {}) {
|
|
15254
15205
|
const maxPayloadLength = options.maxPayloadLength ?? DEFAULT_MAX_PAYLOAD_LENGTH;
|
|
15255
15206
|
if (bytes.byteLength < FRAME_HEADER_LENGTH) {
|
|
15256
|
-
return failure(
|
|
15207
|
+
return failure("FRAME_TOO_SHORT" /* FrameTooShort */, "Frame is shorter than the protocol header.");
|
|
15257
15208
|
}
|
|
15258
15209
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
15259
15210
|
const magic = view.getUint32(0, false);
|
|
15260
15211
|
if (magic !== FRAME_MAGIC) {
|
|
15261
|
-
return failure(
|
|
15212
|
+
return failure("INVALID_MAGIC" /* InvalidMagic */, "Frame magic does not match DWSC.");
|
|
15262
15213
|
}
|
|
15263
15214
|
const version2 = view.getUint16(4, false);
|
|
15264
15215
|
if (version2 !== WIRE_VERSION) {
|
|
15265
|
-
return failure(
|
|
15216
|
+
return failure("UNSUPPORTED_VERSION" /* UnsupportedVersion */, `Unsupported wire version: ${version2}.`);
|
|
15266
15217
|
}
|
|
15267
15218
|
const headerLength = view.getUint16(6, false);
|
|
15268
15219
|
if (headerLength !== FRAME_HEADER_LENGTH) {
|
|
15269
|
-
return failure(
|
|
15220
|
+
return failure(
|
|
15221
|
+
"UNSUPPORTED_HEADER_LENGTH" /* UnsupportedHeaderLength */,
|
|
15222
|
+
`Unsupported header length: ${headerLength}.`
|
|
15223
|
+
);
|
|
15270
15224
|
}
|
|
15271
15225
|
const payloadLength = view.getUint32(16, false);
|
|
15272
15226
|
if (payloadLength > maxPayloadLength) {
|
|
15273
|
-
return failure(
|
|
15227
|
+
return failure(
|
|
15228
|
+
"PAYLOAD_TOO_LARGE" /* PayloadTooLarge */,
|
|
15229
|
+
`Payload length ${payloadLength} exceeds limit ${maxPayloadLength}.`
|
|
15230
|
+
);
|
|
15274
15231
|
}
|
|
15275
15232
|
const expectedLength = FRAME_HEADER_LENGTH + payloadLength;
|
|
15276
15233
|
if (bytes.byteLength !== expectedLength) {
|
|
15277
|
-
return failure(
|
|
15234
|
+
return failure(
|
|
15235
|
+
"PAYLOAD_LENGTH_MISMATCH" /* PayloadLengthMismatch */,
|
|
15236
|
+
`Frame length ${bytes.byteLength} does not match declared length ${expectedLength}.`
|
|
15237
|
+
);
|
|
15278
15238
|
}
|
|
15279
15239
|
return {
|
|
15280
15240
|
ok: true,
|
|
@@ -15302,9 +15262,8 @@ function failure(code, message) {
|
|
|
15302
15262
|
};
|
|
15303
15263
|
}
|
|
15304
15264
|
|
|
15305
|
-
// ../../packages/protocol/
|
|
15306
|
-
var MessageType
|
|
15307
|
-
(function(MessageType2) {
|
|
15265
|
+
// ../../packages/protocol/src/messages.ts
|
|
15266
|
+
var MessageType = /* @__PURE__ */ ((MessageType2) => {
|
|
15308
15267
|
MessageType2[MessageType2["SessionHello"] = 1] = "SessionHello";
|
|
15309
15268
|
MessageType2[MessageType2["SessionHelloAck"] = 2] = "SessionHelloAck";
|
|
15310
15269
|
MessageType2[MessageType2["SessionStart"] = 3] = "SessionStart";
|
|
@@ -15321,10 +15280,13 @@ var MessageType;
|
|
|
15321
15280
|
MessageType2[MessageType2["ControlSystem"] = 772] = "ControlSystem";
|
|
15322
15281
|
MessageType2[MessageType2["ControlClipboard"] = 773] = "ControlClipboard";
|
|
15323
15282
|
MessageType2[MessageType2["LogRecord"] = 1025] = "LogRecord";
|
|
15324
|
-
|
|
15325
|
-
|
|
15283
|
+
return MessageType2;
|
|
15284
|
+
})(MessageType || {});
|
|
15285
|
+
var knownMessageTypes = new Set(
|
|
15286
|
+
Object.values(MessageType).filter((value) => typeof value === "number")
|
|
15287
|
+
);
|
|
15326
15288
|
|
|
15327
|
-
// ../../packages/transport/
|
|
15289
|
+
// ../../packages/transport/src/stream.ts
|
|
15328
15290
|
var DEFAULT_MAX_BUFFERED_BYTES = 16 * 1024 * 1024;
|
|
15329
15291
|
var FrameAssembler = class {
|
|
15330
15292
|
buffer = new Uint8Array();
|
|
@@ -15393,13 +15355,16 @@ function readPayloadLength(bytes) {
|
|
|
15393
15355
|
return view.getUint32(16, false);
|
|
15394
15356
|
}
|
|
15395
15357
|
|
|
15396
|
-
// ../../packages/transport/
|
|
15358
|
+
// ../../packages/transport/src/backpressure.ts
|
|
15397
15359
|
var VIDEO_KEYFRAME_FLAG = 1 << 0;
|
|
15398
15360
|
|
|
15399
|
-
// src/server/create-fastify-app.ts
|
|
15361
|
+
// ../agent/src/server/create-fastify-app.ts
|
|
15400
15362
|
import Fastify from "fastify";
|
|
15363
|
+
import { constants as constants2 } from "fs";
|
|
15364
|
+
import { access as access2, readFile } from "fs/promises";
|
|
15365
|
+
import { extname, join as join2, normalize, relative, sep } from "path";
|
|
15401
15366
|
|
|
15402
|
-
// src/security/origin.ts
|
|
15367
|
+
// ../agent/src/security/origin.ts
|
|
15403
15368
|
function isAllowedOrigin(origin, config2, requestHost) {
|
|
15404
15369
|
if (!origin) {
|
|
15405
15370
|
return true;
|
|
@@ -15409,9 +15374,6 @@ function isAllowedOrigin(origin, config2, requestHost) {
|
|
|
15409
15374
|
if (url2.protocol !== "http:") {
|
|
15410
15375
|
return false;
|
|
15411
15376
|
}
|
|
15412
|
-
if (requestHost !== void 0 && isLocalDevUiOrigin(url2) && isAllowedHost(requestHost, config2)) {
|
|
15413
|
-
return true;
|
|
15414
|
-
}
|
|
15415
15377
|
if (!isAllowedHost(url2.host, config2)) {
|
|
15416
15378
|
return false;
|
|
15417
15379
|
}
|
|
@@ -15454,9 +15416,6 @@ function isLocalHost(host) {
|
|
|
15454
15416
|
const normalized = normalizeHost(host);
|
|
15455
15417
|
return normalized === "127.0.0.1" || normalized === "localhost" || normalized === "::1";
|
|
15456
15418
|
}
|
|
15457
|
-
function isLocalDevUiOrigin(url2) {
|
|
15458
|
-
return url2.port === "5173" && isLocalHost(url2.host);
|
|
15459
|
-
}
|
|
15460
15419
|
function samePort(url2, host) {
|
|
15461
15420
|
return (url2.port || defaultPort(url2.protocol)) === (extractPort(host) || defaultPort(url2.protocol));
|
|
15462
15421
|
}
|
|
@@ -15475,7 +15434,7 @@ function extractPort(host) {
|
|
|
15475
15434
|
return parts.length === 2 ? parts[1] ?? "" : "";
|
|
15476
15435
|
}
|
|
15477
15436
|
|
|
15478
|
-
// src/security/session-token.ts
|
|
15437
|
+
// ../agent/src/security/session-token.ts
|
|
15479
15438
|
import { randomBytes } from "crypto";
|
|
15480
15439
|
function createSessionToken(sessionId, deviceSerial, nowMs, ttlMs, video) {
|
|
15481
15440
|
return {
|
|
@@ -15487,7 +15446,7 @@ function createSessionToken(sessionId, deviceSerial, nowMs, ttlMs, video) {
|
|
|
15487
15446
|
};
|
|
15488
15447
|
}
|
|
15489
15448
|
|
|
15490
|
-
// src/session/session-manager.ts
|
|
15449
|
+
// ../agent/src/session/session-manager.ts
|
|
15491
15450
|
var SessionManager = class {
|
|
15492
15451
|
constructor(adbProvider, now = () => Date.now(), ttlMs = 6e4) {
|
|
15493
15452
|
this.adbProvider = adbProvider;
|
|
@@ -15573,7 +15532,7 @@ var SessionManager = class {
|
|
|
15573
15532
|
}
|
|
15574
15533
|
};
|
|
15575
15534
|
|
|
15576
|
-
// src/security/auth.ts
|
|
15535
|
+
// ../agent/src/security/auth.ts
|
|
15577
15536
|
function validateAgentAuthHeader(authorization, config2) {
|
|
15578
15537
|
if (!config2.authToken) {
|
|
15579
15538
|
return true;
|
|
@@ -15582,7 +15541,7 @@ function validateAgentAuthHeader(authorization, config2) {
|
|
|
15582
15541
|
return values.some((value) => value === `Bearer ${config2.authToken}`);
|
|
15583
15542
|
}
|
|
15584
15543
|
|
|
15585
|
-
// src/server/routes.ts
|
|
15544
|
+
// ../agent/src/server/routes.ts
|
|
15586
15545
|
var noopUpdateRuntimeConfig = () => {
|
|
15587
15546
|
return;
|
|
15588
15547
|
};
|
|
@@ -15910,10 +15869,10 @@ function createShareUrl(bindHost, port) {
|
|
|
15910
15869
|
return `http://${host}:${port}`;
|
|
15911
15870
|
}
|
|
15912
15871
|
|
|
15913
|
-
// src/server/websocket.ts
|
|
15872
|
+
// ../agent/src/server/websocket.ts
|
|
15914
15873
|
var binaryWebSocketProtocol = "droid-webscr.v1";
|
|
15915
15874
|
|
|
15916
|
-
// src/server/create-fastify-app.ts
|
|
15875
|
+
// ../agent/src/server/create-fastify-app.ts
|
|
15917
15876
|
function createLoggerOptions(enabled) {
|
|
15918
15877
|
return enabled === false ? false : {
|
|
15919
15878
|
level: "info",
|
|
@@ -15928,6 +15887,12 @@ async function createFastifyApp(context) {
|
|
|
15928
15887
|
const app = Fastify({
|
|
15929
15888
|
logger: createLoggerOptions(context.logger)
|
|
15930
15889
|
});
|
|
15890
|
+
if (context.webUi?.devMiddleware) {
|
|
15891
|
+
await app.register(middie);
|
|
15892
|
+
app.use(
|
|
15893
|
+
context.webUi.devMiddleware
|
|
15894
|
+
);
|
|
15895
|
+
}
|
|
15931
15896
|
await app.register(websocket, {
|
|
15932
15897
|
options: {
|
|
15933
15898
|
handleProtocols: selectBinaryWebSocketProtocol
|
|
@@ -15970,6 +15935,7 @@ async function createFastifyApp(context) {
|
|
|
15970
15935
|
app.closeActiveDeviceSessions = closeActiveSessions;
|
|
15971
15936
|
app.addHook("preClose", async () => {
|
|
15972
15937
|
await closeActiveSessions({ waitForStartup: true });
|
|
15938
|
+
await context.webUi?.close?.();
|
|
15973
15939
|
});
|
|
15974
15940
|
app.addHook("onRequest", async (request, reply) => {
|
|
15975
15941
|
const origin = request.headers.origin;
|
|
@@ -16117,6 +16083,7 @@ async function createFastifyApp(context) {
|
|
|
16117
16083
|
});
|
|
16118
16084
|
}
|
|
16119
16085
|
);
|
|
16086
|
+
registerWebUiRoutes(app, context.webUi);
|
|
16120
16087
|
return app;
|
|
16121
16088
|
}
|
|
16122
16089
|
function selectBinaryWebSocketProtocol(protocols) {
|
|
@@ -16132,8 +16099,85 @@ function ignoreAsyncError2() {
|
|
|
16132
16099
|
function closeBrowserSocket(socket, code, reason) {
|
|
16133
16100
|
socket.close?.(code, reason);
|
|
16134
16101
|
}
|
|
16102
|
+
function registerWebUiRoutes(app, webUi) {
|
|
16103
|
+
if (!webUi) {
|
|
16104
|
+
return;
|
|
16105
|
+
}
|
|
16106
|
+
app.get("/*", async (request, reply) => {
|
|
16107
|
+
const path = request.url.split("?")[0] ?? "/";
|
|
16108
|
+
if (path.startsWith("/api/") || path === "/api" || path.startsWith("/ws/") || path === "/ws") {
|
|
16109
|
+
return reply.code(404).send({ error: "Not found" });
|
|
16110
|
+
}
|
|
16111
|
+
const file2 = await readWebUiFile(webUi, path);
|
|
16112
|
+
if (file2) {
|
|
16113
|
+
return reply.type(file2.contentType).send(file2.content);
|
|
16114
|
+
}
|
|
16115
|
+
if (webUi.renderIndex) {
|
|
16116
|
+
return reply.type("text/html; charset=utf-8").send(await webUi.renderIndex(request.url));
|
|
16117
|
+
}
|
|
16118
|
+
const index = await readWebUiFile(webUi, "/");
|
|
16119
|
+
if (index) {
|
|
16120
|
+
return reply.type(index.contentType).send(index.content);
|
|
16121
|
+
}
|
|
16122
|
+
return reply.code(404).send({ error: "Not found" });
|
|
16123
|
+
});
|
|
16124
|
+
}
|
|
16125
|
+
async function readWebUiFile(webUi, path) {
|
|
16126
|
+
const staticFile = webUi.staticFiles?.[path] ?? (path === "/" ? webUi.staticFiles?.["/"] : void 0);
|
|
16127
|
+
if (staticFile) {
|
|
16128
|
+
return staticFile;
|
|
16129
|
+
}
|
|
16130
|
+
if (!webUi.staticRoot) {
|
|
16131
|
+
return void 0;
|
|
16132
|
+
}
|
|
16133
|
+
const filePath = resolveStaticFilePath(webUi.staticRoot, path);
|
|
16134
|
+
if (!filePath || !await isReadableFile2(filePath)) {
|
|
16135
|
+
return void 0;
|
|
16136
|
+
}
|
|
16137
|
+
return {
|
|
16138
|
+
content: await readFile(filePath),
|
|
16139
|
+
contentType: contentTypeForPath(filePath)
|
|
16140
|
+
};
|
|
16141
|
+
}
|
|
16142
|
+
function resolveStaticFilePath(root, path) {
|
|
16143
|
+
const normalizedPath = path === "/" ? "/index.html" : path;
|
|
16144
|
+
const decodedPath = decodeURIComponent(normalizedPath);
|
|
16145
|
+
const relativePath = decodedPath.replace(/^\/+/, "");
|
|
16146
|
+
const resolvedPath = normalize(join2(root, relativePath));
|
|
16147
|
+
const relativeToRoot = relative(root, resolvedPath);
|
|
16148
|
+
if (relativeToRoot.startsWith("..") || relativeToRoot.includes(`..${sep}`)) {
|
|
16149
|
+
return void 0;
|
|
16150
|
+
}
|
|
16151
|
+
return resolvedPath;
|
|
16152
|
+
}
|
|
16153
|
+
async function isReadableFile2(path) {
|
|
16154
|
+
try {
|
|
16155
|
+
await access2(path, constants2.R_OK);
|
|
16156
|
+
return true;
|
|
16157
|
+
} catch {
|
|
16158
|
+
return false;
|
|
16159
|
+
}
|
|
16160
|
+
}
|
|
16161
|
+
function contentTypeForPath(path) {
|
|
16162
|
+
switch (extname(path)) {
|
|
16163
|
+
case ".css":
|
|
16164
|
+
return "text/css; charset=utf-8";
|
|
16165
|
+
case ".html":
|
|
16166
|
+
return "text/html; charset=utf-8";
|
|
16167
|
+
case ".js":
|
|
16168
|
+
return "text/javascript; charset=utf-8";
|
|
16169
|
+
case ".json":
|
|
16170
|
+
return "application/json; charset=utf-8";
|
|
16171
|
+
case ".svg":
|
|
16172
|
+
return "image/svg+xml";
|
|
16173
|
+
case ".wasm":
|
|
16174
|
+
return "application/wasm";
|
|
16175
|
+
default:
|
|
16176
|
+
return "application/octet-stream";
|
|
16177
|
+
}
|
|
16178
|
+
}
|
|
16135
16179
|
|
|
16136
|
-
// src/runtime.ts
|
|
16180
|
+
// ../agent/src/runtime.ts
|
|
16137
16181
|
async function startAgent(options = {}) {
|
|
16138
16182
|
const adbProvider = options.adbProvider ?? new SystemAdbProvider();
|
|
16139
16183
|
let runtimeConfig = options.config ?? defaultAgentConfig;
|
|
@@ -16149,7 +16193,8 @@ async function startAgent(options = {}) {
|
|
|
16149
16193
|
rebindRuntime,
|
|
16150
16194
|
updateRuntimeConfig: (nextConfig) => {
|
|
16151
16195
|
runtimeConfig = nextConfig;
|
|
16152
|
-
}
|
|
16196
|
+
},
|
|
16197
|
+
webUi: options.webUi
|
|
16153
16198
|
});
|
|
16154
16199
|
const applyRuntimeRebind = async (bindHost, port) => {
|
|
16155
16200
|
const previousApp = currentApp;
|
|
@@ -16194,9 +16239,17 @@ async function startAgent(options = {}) {
|
|
|
16194
16239
|
await currentApp?.close();
|
|
16195
16240
|
await Promise.all(closingPorts.values());
|
|
16196
16241
|
currentApp = void 0;
|
|
16242
|
+
},
|
|
16243
|
+
get url() {
|
|
16244
|
+
return createRuntimeUrl(runtimeConfig.bindHost, runtimeConfig.port);
|
|
16197
16245
|
}
|
|
16198
16246
|
};
|
|
16199
16247
|
}
|
|
16248
|
+
function createRuntimeUrl(bindHost, port) {
|
|
16249
|
+
const host = bindHost === "0.0.0.0" || bindHost === "::" ? "127.0.0.1" : bindHost;
|
|
16250
|
+
const formattedHost = host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
|
|
16251
|
+
return `http://${formattedHost}:${port}`;
|
|
16252
|
+
}
|
|
16200
16253
|
function isDirectRun(moduleUrl, argv) {
|
|
16201
16254
|
const entrypoint = argv[1];
|
|
16202
16255
|
return entrypoint !== void 0 && pathToFileURL(entrypoint).href === moduleUrl;
|
|
@@ -16238,41 +16291,89 @@ function ignoreAsyncError3() {
|
|
|
16238
16291
|
return void 0;
|
|
16239
16292
|
}
|
|
16240
16293
|
|
|
16241
|
-
//
|
|
16294
|
+
// package.json
|
|
16295
|
+
var package_default = {
|
|
16296
|
+
name: "@arenahito/droid-webscr",
|
|
16297
|
+
version: "0.2.0",
|
|
16298
|
+
private: false,
|
|
16299
|
+
license: "MIT",
|
|
16300
|
+
repository: {
|
|
16301
|
+
type: "git",
|
|
16302
|
+
url: "git+https://github.com/arenahito/droid-webscr.git",
|
|
16303
|
+
directory: "apps/cli"
|
|
16304
|
+
},
|
|
16305
|
+
bin: {
|
|
16306
|
+
"droid-webscr": "dist/bin.js"
|
|
16307
|
+
},
|
|
16308
|
+
files: [
|
|
16309
|
+
"dist",
|
|
16310
|
+
"web",
|
|
16311
|
+
"android",
|
|
16312
|
+
"README.md",
|
|
16313
|
+
"LICENSE"
|
|
16314
|
+
],
|
|
16315
|
+
type: "module",
|
|
16316
|
+
publishConfig: {
|
|
16317
|
+
access: "public"
|
|
16318
|
+
},
|
|
16319
|
+
scripts: {
|
|
16320
|
+
build: "tsup && node ../../tools/package-cli.mjs",
|
|
16321
|
+
"build:dev": "tsup --config tsup.dev.config.ts",
|
|
16322
|
+
lint: "oxlint --config ../../oxlint.json src",
|
|
16323
|
+
test: "vitest run",
|
|
16324
|
+
"type-check": "tsc -p tsconfig.json --noEmit"
|
|
16325
|
+
},
|
|
16326
|
+
dependencies: {
|
|
16327
|
+
"@droid-webscr/agent": "workspace:*",
|
|
16328
|
+
"@fastify/middie": "9.3.2",
|
|
16329
|
+
"@fastify/websocket": "11.2.0",
|
|
16330
|
+
fastify: "5.8.5",
|
|
16331
|
+
pino: "10.3.1"
|
|
16332
|
+
},
|
|
16333
|
+
devDependencies: {
|
|
16334
|
+
vite: "^8.0.16"
|
|
16335
|
+
}
|
|
16336
|
+
};
|
|
16337
|
+
|
|
16338
|
+
// src/cli.ts
|
|
16242
16339
|
async function runCli(argv, runtime = {}) {
|
|
16243
16340
|
const args = argv.slice(2);
|
|
16244
16341
|
const io = createCliIo(runtime);
|
|
16245
|
-
const packageVersion = runtime.packageVersion ?? package_default.version;
|
|
16246
|
-
const start = runtime.startAgent ?? startAgent;
|
|
16247
|
-
if (args.length === 0) {
|
|
16248
|
-
await start();
|
|
16249
|
-
return 0;
|
|
16250
|
-
}
|
|
16251
16342
|
if (args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
|
|
16252
16343
|
io.stdout(createCliHelp());
|
|
16253
16344
|
return 0;
|
|
16254
16345
|
}
|
|
16255
16346
|
if (args.length === 1 && (args[0] === "--version" || args[0] === "-v")) {
|
|
16256
|
-
io.stdout(`${packageVersion}
|
|
16347
|
+
io.stdout(`${runtime.packageVersion ?? "0.0.0"}
|
|
16257
16348
|
`);
|
|
16258
16349
|
return 0;
|
|
16259
16350
|
}
|
|
16260
|
-
|
|
16351
|
+
if (args.length > 0) {
|
|
16352
|
+
io.stderr(`Unknown option: ${args.join(" ")}
|
|
16261
16353
|
|
|
16262
16354
|
`);
|
|
16263
|
-
|
|
16264
|
-
|
|
16355
|
+
io.stderr(createCliHelp());
|
|
16356
|
+
return 1;
|
|
16357
|
+
}
|
|
16358
|
+
const startRuntime = runtime.startRuntime;
|
|
16359
|
+
if (!startRuntime) {
|
|
16360
|
+
throw new Error("No droid-webscr runtime was configured.");
|
|
16361
|
+
}
|
|
16362
|
+
const started = await startRuntime();
|
|
16363
|
+
io.stdout(`droid-webscr is running at ${started.url}
|
|
16364
|
+
`);
|
|
16365
|
+
return 0;
|
|
16265
16366
|
}
|
|
16266
16367
|
function createCliHelp() {
|
|
16267
16368
|
return `Usage: droid-webscr [options]
|
|
16268
16369
|
|
|
16269
|
-
Starts the
|
|
16370
|
+
Starts the integrated droid-webscr local server and web UI.
|
|
16270
16371
|
|
|
16271
16372
|
Options:
|
|
16272
16373
|
-h, --help Show this help text
|
|
16273
16374
|
-v, --version Show the package version
|
|
16274
16375
|
|
|
16275
|
-
The agent
|
|
16376
|
+
The web UI and agent API share http://127.0.0.1:7391 by default.
|
|
16276
16377
|
`;
|
|
16277
16378
|
}
|
|
16278
16379
|
function createCliIo(runtime) {
|
|
@@ -16281,8 +16382,35 @@ function createCliIo(runtime) {
|
|
|
16281
16382
|
stdout: runtime.stdout ?? ((value) => process.stdout.write(value))
|
|
16282
16383
|
};
|
|
16283
16384
|
}
|
|
16385
|
+
|
|
16386
|
+
// src/package-paths.ts
|
|
16387
|
+
import { join as join3 } from "path";
|
|
16388
|
+
var packagedAndroidArtifactFileName = "droid-webscr-server-android.jar";
|
|
16389
|
+
function resolvePackagedWebRoot(packageRoot2) {
|
|
16390
|
+
return join3(packageRoot2, "web");
|
|
16391
|
+
}
|
|
16392
|
+
function resolvePackagedAndroidArtifact(packageRoot2) {
|
|
16393
|
+
return {
|
|
16394
|
+
localPath: join3(packageRoot2, "android", packagedAndroidArtifactFileName),
|
|
16395
|
+
remotePath: deviceServerArtifactRemotePath
|
|
16396
|
+
};
|
|
16397
|
+
}
|
|
16398
|
+
|
|
16399
|
+
// src/bin.ts
|
|
16400
|
+
var packageRoot = dirname2(dirname2(fileURLToPath2(import.meta.url)));
|
|
16401
|
+
async function startPackagedRuntime() {
|
|
16402
|
+
return startAgent({
|
|
16403
|
+
deviceServerArtifact: resolvePackagedAndroidArtifact(packageRoot),
|
|
16404
|
+
webUi: {
|
|
16405
|
+
staticRoot: resolvePackagedWebRoot(packageRoot)
|
|
16406
|
+
}
|
|
16407
|
+
});
|
|
16408
|
+
}
|
|
16284
16409
|
if (isDirectRun(import.meta.url, process.argv)) {
|
|
16285
|
-
runCli(process.argv
|
|
16410
|
+
runCli(process.argv, {
|
|
16411
|
+
packageVersion: package_default.version,
|
|
16412
|
+
startRuntime: startPackagedRuntime
|
|
16413
|
+
}).then(
|
|
16286
16414
|
(exitCode) => {
|
|
16287
16415
|
process.exitCode = exitCode;
|
|
16288
16416
|
},
|
|
@@ -16293,7 +16421,6 @@ if (isDirectRun(import.meta.url, process.argv)) {
|
|
|
16293
16421
|
);
|
|
16294
16422
|
}
|
|
16295
16423
|
export {
|
|
16296
|
-
|
|
16297
|
-
runCli
|
|
16424
|
+
startPackagedRuntime
|
|
16298
16425
|
};
|
|
16299
16426
|
//# sourceMappingURL=bin.js.map
|