@swmansion/argent 0.30.2-next.17 → 0.30.2-next.19
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/dist/cli-cmds.mjs +1 -1
- package/dist/installer.mjs +1 -1
- package/dist/tool-args.generated.d.ts +2 -0
- package/dist/tool-server.cjs +53 -14
- package/package.json +1 -1
package/dist/cli-cmds.mjs
CHANGED
|
@@ -35594,7 +35594,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
35594
35594
|
var SESSION_ID2 = randomUUID5();
|
|
35595
35595
|
function readCliVersion() {
|
|
35596
35596
|
if (true) {
|
|
35597
|
-
return "0.30.2-next.
|
|
35597
|
+
return "0.30.2-next.19";
|
|
35598
35598
|
}
|
|
35599
35599
|
return "0.0.0";
|
|
35600
35600
|
}
|
package/dist/installer.mjs
CHANGED
|
@@ -16900,7 +16900,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
16900
16900
|
var SESSION_ID = randomUUID4();
|
|
16901
16901
|
function readCliVersion() {
|
|
16902
16902
|
if (true) {
|
|
16903
|
-
return "0.30.2-next.
|
|
16903
|
+
return "0.30.2-next.19";
|
|
16904
16904
|
}
|
|
16905
16905
|
return "0.0.0";
|
|
16906
16906
|
}
|
|
@@ -53,6 +53,8 @@ export interface ArgentToolArgs {
|
|
|
53
53
|
force?: boolean;
|
|
54
54
|
/** Android only: boot the emulator with audio output enabled. Defaults to false: argent boots emulators MUTED so several agent-driven devices don't all play sound on the host machine; pass `true` when the task involves playing, hearing, or testing audio. Takes effect at boot: if the emulator is already running muted, add `force: true` to reboot it with sound. A boot snapshot saved in the other audio mode can't be reused, so the first boot after toggling is a slower cold boot. The `boot-sound` argent flag flips this default to true. Ignored on iOS/Vega/HarmonyOS/Electron, which argent never mutes. */
|
|
55
55
|
sound?: boolean;
|
|
56
|
+
/** Android on a macOS host only: boot the emulator with guest Vulkan. Defaults to false: guest Vulkan crashes Chrome's GPU process, which breaks Chrome and Custom Tab sign-in flows. Without it apps find no Vulkan device, although the guest still lists the Vulkan features, so a Vulkan-only renderer such as WebGPU (react-native-wgpu) draws nothing; pass `true` to test one. Takes effect at boot: an emulator already running in the other mode is reused with a `note`, and `force: true` reboots it. A boot snapshot saved in the other mode can't be reused, so the first boot after toggling is a slower cold boot. The `ARGENT_EMULATOR_GUEST_VULKAN` env var flips this default to true. Ignored on other hosts and platforms. */
|
|
57
|
+
guestVulkan?: boolean;
|
|
56
58
|
/** iOS only: boot the simulator core WITHOUT opening its GUI window (Simulator.app, or Device Hub on Xcode 27+). The device still streams via simulator-server; used by Argent Lens. Set the `ARGENT_SIMULATOR_NO_WINDOW` env var (1/true/yes) to force this host-wide without passing the flag per call (the iOS analog of `ARGENT_EMULATOR_NO_WINDOW`). Ignored on Android/Vega/HarmonyOS/Electron, which have no equivalent GUI step. */
|
|
57
59
|
headless?: boolean;
|
|
58
60
|
/** Electron: path to the Electron app to launch. Either a packaged .app bundle / executable, or a project directory whose package.json points the Electron binary at the entry script. Provide exactly one of `udid`, `avdName`, `vvdImage`, `harmonyInstance`, or `electronAppPath`. */
|
package/dist/tool-server.cjs
CHANGED
|
@@ -100945,7 +100945,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
100945
100945
|
var SESSION_ID = (0, import_node_crypto3.randomUUID)();
|
|
100946
100946
|
function readCliVersion() {
|
|
100947
100947
|
if (true) {
|
|
100948
|
-
return "0.30.2-next.
|
|
100948
|
+
return "0.30.2-next.19";
|
|
100949
100949
|
}
|
|
100950
100950
|
return "0.0.0";
|
|
100951
100951
|
}
|
|
@@ -137046,6 +137046,9 @@ function iosHeadlessFromEnv() {
|
|
|
137046
137046
|
function androidHeadlessFromEnv() {
|
|
137047
137047
|
return truthyEnv("ARGENT_EMULATOR_NO_WINDOW");
|
|
137048
137048
|
}
|
|
137049
|
+
function androidGuestVulkanFromEnv() {
|
|
137050
|
+
return truthyEnv("ARGENT_EMULATOR_GUEST_VULKAN");
|
|
137051
|
+
}
|
|
137049
137052
|
|
|
137050
137053
|
// ../tool-server/src/tools/devices/boot-device.ts
|
|
137051
137054
|
init_device_info();
|
|
@@ -137798,6 +137801,9 @@ var zodSchema9 = external_exports.object({
|
|
|
137798
137801
|
sound: external_exports.boolean().optional().describe(
|
|
137799
137802
|
"Android only: boot the emulator with audio output enabled. Defaults to false: argent boots emulators MUTED so several agent-driven devices don't all play sound on the host machine; pass `true` when the task involves playing, hearing, or testing audio. Takes effect at boot: if the emulator is already running muted, add `force: true` to reboot it with sound. A boot snapshot saved in the other audio mode can't be reused, so the first boot after toggling is a slower cold boot. The `boot-sound` argent flag flips this default to true. Ignored on iOS/Vega<flag:harmonyos>/HarmonyOS</flag:harmonyos>/Electron, which argent never mutes."
|
|
137800
137803
|
),
|
|
137804
|
+
guestVulkan: external_exports.boolean().optional().describe(
|
|
137805
|
+
"Android on a macOS host only: boot the emulator with guest Vulkan. Defaults to false: guest Vulkan crashes Chrome's GPU process, which breaks Chrome and Custom Tab sign-in flows. Without it apps find no Vulkan device, although the guest still lists the Vulkan features, so a Vulkan-only renderer such as WebGPU (react-native-wgpu) draws nothing; pass `true` to test one. Takes effect at boot: an emulator already running in the other mode is reused with a `note`, and `force: true` reboots it. A boot snapshot saved in the other mode can't be reused, so the first boot after toggling is a slower cold boot. The `ARGENT_EMULATOR_GUEST_VULKAN` env var flips this default to true. Ignored on other hosts and platforms."
|
|
137806
|
+
),
|
|
137801
137807
|
headless: external_exports.boolean().optional().describe(
|
|
137802
137808
|
"iOS only: boot the simulator core WITHOUT opening its GUI window (Simulator.app, or Device Hub on Xcode 27+). The device still streams via simulator-server; used by Argent Lens. Set the `ARGENT_SIMULATOR_NO_WINDOW` env var (1/true/yes) to force this host-wide without passing the flag per call (the iOS analog of `ARGENT_EMULATOR_NO_WINDOW`). Ignored on Android/Vega<flag:harmonyos>/HarmonyOS</flag:harmonyos>/Electron, which have no equivalent GUI step."
|
|
137803
137809
|
),
|
|
@@ -137865,14 +137871,27 @@ function selectGpuMode() {
|
|
|
137865
137871
|
}
|
|
137866
137872
|
return process.platform === "linux" ? "swiftshader" : "auto";
|
|
137867
137873
|
}
|
|
137874
|
+
function guestVulkanArgs(guestVulkan) {
|
|
137875
|
+
if (process.platform !== "darwin") return [];
|
|
137876
|
+
return ["-feature", guestVulkan ? "Vulkan" : "-Vulkan"];
|
|
137877
|
+
}
|
|
137878
|
+
async function runningGuestVulkanNote(serial, guestVulkan) {
|
|
137879
|
+
if (process.platform !== "darwin") return void 0;
|
|
137880
|
+
const prop = await adbShell(serial, "getprop ro.boot.hardware.vulkan", { timeoutMs: 5e3 }).then((out) => out.trim()).catch(() => null);
|
|
137881
|
+
if (prop === null || prop !== "" === guestVulkan) return void 0;
|
|
137882
|
+
return guestVulkan ? "This emulator was already running without guest Vulkan, so apps find no Vulkan device. Pass `force: true` to reboot it with guest Vulkan." : "This emulator was already running with guest Vulkan, which can crash Chrome's GPU process. Pass `force: true` to reboot it without guest Vulkan.";
|
|
137883
|
+
}
|
|
137868
137884
|
var BOOT_POLL_INTERVALS_MS = {
|
|
137869
137885
|
serialByAvd: 1500,
|
|
137870
137886
|
// findSerialByAvdName: re-scan when >1 new emulator appeared
|
|
137871
137887
|
adbRegister: 1e3,
|
|
137872
137888
|
// attemptBoot stage 2: re-scan adb devices for the new serial
|
|
137873
|
-
earlyExit: 500
|
|
137889
|
+
earlyExit: 500,
|
|
137874
137890
|
// createEarlyExitRacer: re-check the crash latch during a blocking adb call
|
|
137891
|
+
serialGone: 500
|
|
137892
|
+
// awaitEmulatorsGone: re-scan adb devices for a killed emulator
|
|
137875
137893
|
};
|
|
137894
|
+
var EMULATOR_GONE_BUDGET_MS = 3e4;
|
|
137876
137895
|
var FRAME_PROBE = "screencap -p 2>/dev/null | wc -c | awk '$1>20000{print 1;exit} {print 0}'";
|
|
137877
137896
|
async function killEmulatorQuietly(serial, child) {
|
|
137878
137897
|
if (serial) {
|
|
@@ -137952,18 +137971,28 @@ async function findSerialByAvdName(avdName, deadline) {
|
|
|
137952
137971
|
}
|
|
137953
137972
|
return null;
|
|
137954
137973
|
}
|
|
137955
|
-
async function
|
|
137974
|
+
async function listEmulatorSerials() {
|
|
137956
137975
|
const { stdout } = await runAdb(["devices"], { timeoutMs: 3e3 }).catch(() => ({
|
|
137957
137976
|
stdout: "",
|
|
137958
137977
|
stderr: ""
|
|
137959
137978
|
}));
|
|
137960
|
-
const lines = stdout.split("\n");
|
|
137961
137979
|
const now = [];
|
|
137962
|
-
for (const line of
|
|
137980
|
+
for (const line of stdout.split("\n")) {
|
|
137963
137981
|
const m = line.match(/^(emulator-\d+)\s+/);
|
|
137964
137982
|
if (m) now.push(m[1]);
|
|
137965
137983
|
}
|
|
137966
|
-
return now
|
|
137984
|
+
return now;
|
|
137985
|
+
}
|
|
137986
|
+
async function listNewEmulatorSerials(before) {
|
|
137987
|
+
return (await listEmulatorSerials()).filter((s) => !before.has(s));
|
|
137988
|
+
}
|
|
137989
|
+
async function awaitEmulatorsGone(serials) {
|
|
137990
|
+
const deadline = Date.now() + EMULATOR_GONE_BUDGET_MS;
|
|
137991
|
+
while (serials.length > 0 && Date.now() < deadline) {
|
|
137992
|
+
const listed = await listEmulatorSerials();
|
|
137993
|
+
if (!serials.some((s) => listed.includes(s))) return;
|
|
137994
|
+
await new Promise((r) => setTimeout(r, BOOT_POLL_INTERVALS_MS.serialGone));
|
|
137995
|
+
}
|
|
137967
137996
|
}
|
|
137968
137997
|
async function bootIos(udid, registry2, force, headless) {
|
|
137969
137998
|
if (process.platform !== "darwin") {
|
|
@@ -138263,7 +138292,10 @@ async function bootAndroidImpl(params) {
|
|
|
138263
138292
|
await ensureDep("adb");
|
|
138264
138293
|
await ensureDep("emulator");
|
|
138265
138294
|
const gpuMode = selectGpuMode();
|
|
138266
|
-
const extraEmulatorArgs =
|
|
138295
|
+
const extraEmulatorArgs = [
|
|
138296
|
+
...androidHeadlessFromEnv() ? ["-no-window"] : [],
|
|
138297
|
+
...guestVulkanArgs(params.guestVulkan)
|
|
138298
|
+
];
|
|
138267
138299
|
const hardeningArgs = launchHardeningArgs(params.sound);
|
|
138268
138300
|
for (const msg of linuxBootDiagnostics(params.avdName) ?? []) {
|
|
138269
138301
|
console.warn(`[boot-device:linux] ${msg}`);
|
|
@@ -138312,26 +138344,31 @@ async function bootAndroidImpl(params) {
|
|
|
138312
138344
|
});
|
|
138313
138345
|
const existingDevices = await listAndroidDevices().catch(() => []);
|
|
138314
138346
|
let hotBootFailureReason;
|
|
138347
|
+
const dropKilledEmulator = async (serial) => {
|
|
138348
|
+
await awaitEmulatorsGone([serial]);
|
|
138349
|
+
const refreshed = await listAndroidDevices().catch(() => existingDevices);
|
|
138350
|
+
existingDevices.splice(0, existingDevices.length, ...refreshed);
|
|
138351
|
+
};
|
|
138315
138352
|
const alreadyRunning = existingDevices.find(
|
|
138316
138353
|
(d) => d.isEmulator && d.avdName === params.avdName && d.state === "device"
|
|
138317
138354
|
);
|
|
138318
138355
|
if (alreadyRunning) {
|
|
138319
138356
|
if (params.force) {
|
|
138320
138357
|
await killEmulatorQuietly(alreadyRunning.serial);
|
|
138321
|
-
|
|
138322
|
-
existingDevices.splice(0, existingDevices.length, ...refreshed);
|
|
138358
|
+
await dropKilledEmulator(alreadyRunning.serial);
|
|
138323
138359
|
} else {
|
|
138324
138360
|
try {
|
|
138325
138361
|
await assertScreencapAlive(alreadyRunning.serial);
|
|
138362
|
+
const note = await runningGuestVulkanNote(alreadyRunning.serial, params.guestVulkan);
|
|
138326
138363
|
return {
|
|
138327
138364
|
platform: "android",
|
|
138328
138365
|
serial: alreadyRunning.serial,
|
|
138329
138366
|
avdName: params.avdName,
|
|
138330
|
-
booted: true
|
|
138367
|
+
booted: true,
|
|
138368
|
+
...note ? { note } : {}
|
|
138331
138369
|
};
|
|
138332
138370
|
} catch (_err) {
|
|
138333
|
-
|
|
138334
|
-
existingDevices.splice(0, existingDevices.length, ...refreshed);
|
|
138371
|
+
await dropKilledEmulator(alreadyRunning.serial);
|
|
138335
138372
|
}
|
|
138336
138373
|
}
|
|
138337
138374
|
}
|
|
@@ -138384,6 +138421,7 @@ async function bootAndroidImpl(params) {
|
|
|
138384
138421
|
};
|
|
138385
138422
|
} catch (err) {
|
|
138386
138423
|
hotBootFailureReason = err instanceof Error ? err.message : String(err);
|
|
138424
|
+
await awaitEmulatorsGone(await listNewEmulatorSerials(serialsBefore));
|
|
138387
138425
|
const refreshed = new Set(
|
|
138388
138426
|
(await listAndroidDevices().catch(() => [])).map((d) => d.serial)
|
|
138389
138427
|
);
|
|
@@ -138949,7 +138987,7 @@ function createBootDeviceTool(registry2) {
|
|
|
138949
138987
|
description: `Start an iOS simulator, launch an Android emulator, start a Vega (Fire TV) Virtual Device, <flag:harmonyos>start a HarmonyOS emulator, </flag:harmonyos>or spawn an Electron app and wait until it is ready to accept interactions.
|
|
138950
138988
|
Pick the platform by which argument you pass: 'udid' for an iOS simulator from list-devices, 'avdName' for an Android AVD (a serial is assigned automatically), 'vvdImage' for a Vega VVD (the 'vvdImage' of a vega device from list-devices, e.g. 'tv'), <flag:harmonyos>'harmonyInstance' for a HarmonyOS emulator instance (the 'name' of a harmony device from list-devices), </flag:harmonyos>or 'electronAppPath' for an Electron app (a CDP remote-debugging port is picked automatically, or pass 'electronPort' to fix one).
|
|
138951
138989
|
Use at the start of a session once you have picked a target.
|
|
138952
|
-
Returns a tagged payload: { platform: 'ios', udid, booted } or { platform: 'android', serial, avdName, booted } or { platform: 'vega', serial, vvdImage, booted } or <flag:harmonyos>{ platform: 'harmony', udid, instanceName, booted, note? } or </flag:harmonyos>{ platform: 'chromium', id, port, pid, booted } (an Electron app boots as a Chromium/CDP device).
|
|
138990
|
+
Returns a tagged payload: { platform: 'ios', udid, booted } or { platform: 'android', serial, avdName, booted, note? } or { platform: 'vega', serial, vvdImage, booted } or <flag:harmonyos>{ platform: 'harmony', udid, instanceName, booted, note? } or </flag:harmonyos>{ platform: 'chromium', id, port, pid, booted } (an Electron app boots as a Chromium/CDP device).
|
|
138953
138991
|
Android boots take 2\u201310 minutes depending on machine and cold/warm state; the tool transparently hot-boots from the AVD's default_boot snapshot when usable and falls back to cold boot otherwise. Vega starts the single SDK-managed VVD via the vega CLI (~10s) and returns once it reports running. If an Android/Electron boot stage fails, the tool terminates the device it spawned so the next retry starts clean.<flag:harmonyos>
|
|
138954
138992
|
HarmonyOS hands the instance to DevEco Studio's Emulator manager, then waits for it to register with 'hdc' and returns its connect key as 'udid', the id the interaction tools drive. The manager itself reports no readiness signal and never names a port, so an instance that is already running is left alone unless you pass 'force: true'; when the key could not be resolved the payload names the instance instead, and a 'note' is present whenever the boot left something unproven: no key and why, or a key that is not yet answering or could not be checked against the instance. Huawei serves the emulator images only within mainland China, so a host outside it usually has no instance to start; one that already has an image is started like any other.</flag:harmonyos>`,
|
|
138955
138993
|
alwaysLoad: true,
|
|
@@ -139012,7 +139050,8 @@ HarmonyOS hands the instance to DevEco Studio's Emulator manager, then waits for
|
|
|
139012
139050
|
// An explicit argument always wins; the `boot-sound` flag only moves
|
|
139013
139051
|
// the default when the caller left `sound` unset. Read live per call
|
|
139014
139052
|
// so `argent enable/disable boot-sound` applies without a restart.
|
|
139015
|
-
sound: params.sound ?? isFlagEnabled("boot-sound")
|
|
139053
|
+
sound: params.sound ?? isFlagEnabled("boot-sound"),
|
|
139054
|
+
guestVulkan: params.guestVulkan ?? androidGuestVulkanFromEnv()
|
|
139016
139055
|
});
|
|
139017
139056
|
}
|
|
139018
139057
|
if (hasVega) {
|
package/package.json
CHANGED