stim 1.1.0 → 1.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 -0
- package/dist/{android-CC5bUer7.mjs → android-BW8i_YxU.mjs} +1 -1
- package/dist/{android-DnZlT3aU.mjs → android-Bcmev2s2.mjs} +86 -31
- package/dist/{android-xmyGBNy5.mjs → android-K63_0UfF.mjs} +77 -15
- package/dist/{android-cas-DGlTStWu.mjs → android-cas-D6HPZ6UQ.mjs} +6 -6
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/{app-install-oZIQRbdD.mjs → app-install-NFxUahnH.mjs} +25 -17
- package/dist/{build-lock-vE45ZzJZ.mjs → build-lock-BsVoLDaq.mjs} +6 -6
- package/dist/{build-slots-CgacA9zQ.mjs → build-slots-D0b6sJyo.mjs} +3 -3
- package/dist/{cache-manifest-oeH18ERr.mjs → cache-manifest-Cu4_Znw9.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +13 -13
- package/dist/collector-run.d.mts +1 -0
- package/dist/collector-run.mjs +6 -6
- package/dist/{config-D7uu8Gbq.mjs → config-CMtIaTk9.mjs} +1 -1
- package/dist/{deps-64wVnpZc.mjs → deps-BLBsTNDS.mjs} +2 -2
- package/dist/{dev-client-Bvky1hya.mjs → dev-client-RpvXxCXV.mjs} +72 -9
- package/dist/{device-DJKv5Qej.mjs → device-CoCPmazS.mjs} +5 -5
- package/dist/{device-lease-D-G3SgVe.mjs → device-lease-Dpik41RY.mjs} +3 -3
- package/dist/{device-pool-BlHXnYYs.mjs → device-pool-B5pEVa3t.mjs} +3 -3
- package/dist/{device-remote-CCgkG82J.mjs → device-remote-E81KAdXf.mjs} +8 -8
- package/dist/{doctor-DlVxTtMq.mjs → doctor-CqPeMsSm.mjs} +19 -26
- package/dist/{doctor-BRF9aAJ3.mjs → doctor-D_CX7ib5.mjs} +10 -10
- package/dist/{error-diagnostics-B5IJwv3-.mjs → error-diagnostics-Dw8Gn3yw.mjs} +8 -8
- package/dist/{exec-bsN9MJXb.mjs → exec-CyylIdq9.mjs} +4 -2
- package/dist/{gc-DhXdgSdt.mjs → gc-B7KkDinF.mjs} +39 -25
- package/dist/{guide-DrhrDBo5.mjs → guide-BS2Xc24o.mjs} +220 -36
- package/dist/{ios-CK1Vrk6Q.mjs → ios-B7KLgIp5.mjs} +38 -26
- package/dist/{ios-BZxKPuqP.mjs → ios-D1h1Di39.mjs} +79 -10
- package/dist/{ios-device-CYbuRNXR.mjs → ios-device-D3pzTKQE.mjs} +1 -1
- package/dist/{ios-device-CdSm0GDw.mjs → ios-device-xNt0Lg6v.mjs} +2 -2
- package/dist/{logs-Dxoy16Qv.mjs → logs-DcX9AvRF.mjs} +3 -3
- package/dist/{metro-B01H3EuD.mjs → metro-COslRK_F.mjs} +3 -3
- package/dist/{ownership-D8HmSv2E.mjs → ownership-CGPart6T.mjs} +3 -3
- package/dist/{ownership-B9QIdQOw.mjs → ownership-CYOyqxUo.mjs} +4 -4
- package/dist/{ownership-claim-CeJLEpjD.mjs → ownership-claim-7zRxxTfZ.mjs} +1 -1
- package/dist/{project-COj6nzzh.mjs → project-BBTVABUz.mjs} +2 -2
- package/dist/{reclaim-BPvN2HlP.mjs → reclaim-C5Jmuahx.mjs} +9 -8
- package/dist/{reload-DYZEBbZy.mjs → reload-Z8nKifAk.mjs} +7 -7
- package/dist/{remote-cache-DOi5-zLj.mjs → remote-cache-DDmJ1Roq.mjs} +73 -13
- package/dist/{server-bare-BYHqEeyw.mjs → server-bare-DEk37Mz2.mjs} +7 -2
- package/dist/{server-expo-BEMr_m6p.mjs → server-expo-C3ktAwUG.mjs} +4 -4
- package/dist/server-expo-Drd7ksHu.mjs +2 -0
- package/dist/{settings-BSwrY4FZ.mjs → settings-DwU1_U_q.mjs} +26 -5
- package/dist/{start-ByCylYtB.mjs → start-BrY4EuIg.mjs} +10 -10
- package/dist/{state-IYEY-zi8.mjs → state-CZ-ER-8d.mjs} +1 -1
- package/dist/{stats-wqxPm7Tv.mjs → stats-BCWEVLrM.mjs} +1 -1
- package/dist/{stats-DZ4Q5J-7.mjs → stats-BsF15Bti.mjs} +3 -3
- package/dist/{status-Dia0XTqG.mjs → status-DFI1Hfpg.mjs} +46 -16
- package/dist/{stop-D6o5zAdm.mjs → stop-B7DR4awK.mjs} +2 -2
- package/dist/{stop-BApyaF21.mjs → stop-Btg770vV.mjs} +9 -9
- package/dist/supervisor-run.mjs +4 -4
- package/dist/{workspace-process-lock-CxOO9-pf.mjs → workspace-process-lock-BKfdys1q.mjs} +1 -1
- package/dist/{worktree-DxEmUI_n.mjs → worktree-BPTbI-LN.mjs} +16 -16
- package/dist/{worktree-Dx3ZC5lS.mjs → worktree-C79xx_kM.mjs} +7 -3
- package/dist/{xcode-CDB6fytw.mjs → xcode-DeKCribl.mjs} +190 -63
- package/package.json +5 -5
- package/shim/bundle-response.cjs +5 -0
- package/dist/server-expo-rb0k-0w7.mjs +0 -2
package/README.md
CHANGED
|
@@ -58,6 +58,13 @@ one native platform is in scope; shared project checks still run. Doctor also
|
|
|
58
58
|
prints the running CLI version and the `stim` installation resolved from PATH,
|
|
59
59
|
and flags a resolved installation that is older than another available one.
|
|
60
60
|
|
|
61
|
+
For parallel iOS work, SimSlim is recommended as an optional way to reduce
|
|
62
|
+
simulator background services and memory use. Run `stim guide lifecycle simslim`
|
|
63
|
+
to review the service tradeoffs and configure a profile. Doctor recommends the
|
|
64
|
+
setup without installing or enabling it. When a simulator cannot start
|
|
65
|
+
processes, Stim bounds the wait and reports observed host memory pressure when
|
|
66
|
+
available; free memory before retrying. A timeout alone does not prove OOM.
|
|
67
|
+
|
|
61
68
|
For stale Android CMake launcher findings, stop native builds and run
|
|
62
69
|
`stim doctor --fix --platform android` in the affected checkout. It clears
|
|
63
70
|
affected ignored, untracked generated `.cxx` configurations in the app and
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { C as withConfigLock, S as upsertProject, f as getProject, g as loadConfig, l as getConcurrencyLimits, y as saveConfig } from "./config-
|
|
1
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
+
import { C as withConfigLock, S as upsertProject, b as setDevice, f as getProject, g as loadConfig, l as getConcurrencyLimits, y as saveConfig } from "./config-CMtIaTk9.mjs";
|
|
3
3
|
import { r as createNdjsonWriter } from "./ndjson-DcAtEx_K.mjs";
|
|
4
|
-
import { D as workspaceLogsDir, T as workspaceDir, _ as writeWorkspaceState, g as writeWorkspaceLaunch, n as MODE_EXPO, p as readWorkspaceState, t as MODE_BARE, v as emulatorLogFile } from "./state-
|
|
5
|
-
import { C as removeTemporaryEntry, S as makeTemporaryDirectory, g as repoRoot, s as gitCommonDir } from "./worktree-
|
|
6
|
-
import { a as findProjectRoot, c as projectShortcut, i as detectIsExpo, n as detectAndroidPackage, r as detectBundleId, t as appProjectProblem } from "./project-
|
|
4
|
+
import { D as workspaceLogsDir, T as workspaceDir, _ as writeWorkspaceState, g as writeWorkspaceLaunch, n as MODE_EXPO, p as readWorkspaceState, t as MODE_BARE, v as emulatorLogFile } from "./state-CZ-ER-8d.mjs";
|
|
5
|
+
import { C as removeTemporaryEntry, S as makeTemporaryDirectory, g as repoRoot, s as gitCommonDir } from "./worktree-C79xx_kM.mjs";
|
|
6
|
+
import { a as findProjectRoot, c as projectShortcut, i as detectIsExpo, n as detectAndroidPackage, r as detectBundleId, t as appProjectProblem } from "./project-BBTVABUz.mjs";
|
|
7
7
|
import { r as waitForChild, t as createLineReader } from "./process-output-C7IlIzd7.mjs";
|
|
8
|
-
import { i as resolveProjectMetro, r as pidExists } from "./metro-
|
|
9
|
-
import { n as verifyCollectorOwnership, r as readCollectors } from "./ownership-
|
|
10
|
-
import { a as easAuthNote, c as loadProjectProvider, d as resolveEasCliBin, f as resolveRemote, i as checkEasAuth, n as UPLOAD_TIMEOUT_MS, o as exitAfterFlush, p as uploadRemote, r as cacheLevel, s as isEasAuthFailureText, t as RESOLVE_TIMEOUT_MS, x as parkedMaxSetting } from "./remote-cache-
|
|
11
|
-
import { A as
|
|
8
|
+
import { i as resolveProjectMetro, r as pidExists } from "./metro-COslRK_F.mjs";
|
|
9
|
+
import { n as verifyCollectorOwnership, r as readCollectors } from "./ownership-CGPart6T.mjs";
|
|
10
|
+
import { a as easAuthNote, c as loadProjectProvider, d as resolveEasCliBin, f as resolveRemote, i as checkEasAuth, n as UPLOAD_TIMEOUT_MS, o as exitAfterFlush, p as uploadRemote, r as cacheLevel, s as isEasAuthFailureText, t as RESOLVE_TIMEOUT_MS, x as parkedMaxSetting } from "./remote-cache-DDmJ1Roq.mjs";
|
|
11
|
+
import { A as resolveSettings, B as artifactCachePolicy, D as remoteDeviceSettingError, E as remoteAndroidSetting, F as tunnelModeSetting, H as optimizationBuildProfile, I as unknownSettingKeys, N as settingShapeErrors, R as detectProviders, T as publicUrlSetting, U as resolveOptimizations, V as compilerCacheFallbackMessage, a as SETTING_SHAPE_REMEDY, d as cacheProviderSettingError, j as settingFile, k as resolveCacheProviderConfig, r as REMOTE_DEVICE_BACKENDS, s as androidAvdConfigSettingError, u as androidDataPartitionSizeGbSettingError, x as metroWarmupUrlSetting } from "./settings-DwU1_U_q.mjs";
|
|
12
12
|
import { _ as launchErrorPreview, c as launchErrorReport, g as stepTimer, h as stepClock, i as formatDuration, l as phaseLine, n as appReadinessMessage, p as shortHash } from "./command-output-8wHMEde0.mjs";
|
|
13
|
-
import { D as verifyAndroidReleaseLaunch, E as unverifiedLaunchLines, O as verifyLaunch, S as launchAndroidReleaseApp, _ as installConflictKind, c as RELEASE_VERIFY_WAIT_MS, d as androidDevClientUrl, g as installAndroidApp, h as deviceShellArg, i as LAUNCH_BUNDLING, n as DEFAULT_METRO_PORT, o as LAUNCH_FATAL, s as LAUNCH_UNVERIFIED, t as ADB_INSTALL_TIMEOUT_MS, u as androidAppProcess, x as launchAndroidApp } from "./app-install-
|
|
14
|
-
import { C as untrackedNativeFiles, D as readAssetManifest, E as compareAssetManifests, S as untrackedMissLine, T as captureAssetManifest, _ as providerUploadOutcome, b as storeBuild, c as buildCacheKey, d as filesystemBuildCapability, f as fingerprintDiffRecord, g as providerDownloadPath, h as prepareProviderDownloadDir, i as releaseBuildLock, l as describeFingerprintMiss, m as fingerprintProject, n as acquireBuildLock, o as takeoverLine, p as fingerprintDiffSuffix, s as waitForBuild, t as WAIT_CEILING_MS, v as refingerprintAfterMutation, w as assetDiffReason, x as storedAssetManifest, y as resolveBuild } from "./build-lock-
|
|
15
|
-
import { r as claimFailure } from "./ownership-claim-
|
|
16
|
-
import { a as lostLine, c as releaseLeaseOnSignal, i as leaseExpiryText, l as runLease, n as DEBUG_VERIFY_STEP_MS, o as lostRefusal, r as acquireRunLease, s as parseDeviceWait, t as selectFromPool, u as waitFlagConflict } from "./device-pool-
|
|
17
|
-
import { r as releaseBuildSlot, t as acquireBuildSlot } from "./build-slots-
|
|
18
|
-
import { c as ensureWorkspaceStorageSafely, d as noMetroMessage, f as noMetroRemedy, i as detectEntryFile, n as pickDevClientScheme, o as needsPrebuild, p as resolveMetroWithRetry, s as runPrebuild, t as devClientScheme, u as launchOutcomeRecord } from "./dev-client-
|
|
19
|
-
import { a as statsProjectKey, i as recordRunStats, n as readRunEstimates, t as createRunRecorder } from "./stats-
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import { a as ensureMetroReachable, b as ownedSessionName, l as resolveRemoteContext, n as binOnPath, o as ensureRemoteBootOwned, s as remoteAndroidDeps } from "./device-remote-
|
|
23
|
-
import { t as cleanLine } from "./server-expo-
|
|
24
|
-
import { a as buildAndroid, c as CCACHE_NOT_RUN, f as resolveCcache, l as CCACHE_UNAVAILABLE, n as resolveAndroidCas, o as productFlavorRefusal, p as formatDiagnostic, r as resolveAndroidCompilerCache, s as readProductFlavors, u as ccacheActivityLine } from "./android-cas-
|
|
13
|
+
import { D as verifyAndroidReleaseLaunch, E as unverifiedLaunchLines, O as verifyLaunch, S as launchAndroidReleaseApp, _ as installConflictKind, c as RELEASE_VERIFY_WAIT_MS, d as androidDevClientUrl, g as installAndroidApp, h as deviceShellArg, i as LAUNCH_BUNDLING, l as VERIFY_TIMEOUT_MS, n as DEFAULT_METRO_PORT, o as LAUNCH_FATAL, s as LAUNCH_UNVERIFIED, t as ADB_INSTALL_TIMEOUT_MS, u as androidAppProcess, x as launchAndroidApp } from "./app-install-NFxUahnH.mjs";
|
|
14
|
+
import { C as untrackedNativeFiles, D as readAssetManifest, E as compareAssetManifests, S as untrackedMissLine, T as captureAssetManifest, _ as providerUploadOutcome, b as storeBuild, c as buildCacheKey, d as filesystemBuildCapability, f as fingerprintDiffRecord, g as providerDownloadPath, h as prepareProviderDownloadDir, i as releaseBuildLock, l as describeFingerprintMiss, m as fingerprintProject, n as acquireBuildLock, o as takeoverLine, p as fingerprintDiffSuffix, s as waitForBuild, t as WAIT_CEILING_MS, v as refingerprintAfterMutation, w as assetDiffReason, x as storedAssetManifest, y as resolveBuild } from "./build-lock-BsVoLDaq.mjs";
|
|
15
|
+
import { r as claimFailure } from "./ownership-claim-7zRxxTfZ.mjs";
|
|
16
|
+
import { a as lostLine, c as releaseLeaseOnSignal, i as leaseExpiryText, l as runLease, n as DEBUG_VERIFY_STEP_MS, o as lostRefusal, r as acquireRunLease, s as parseDeviceWait, t as selectFromPool, u as waitFlagConflict } from "./device-pool-B5pEVa3t.mjs";
|
|
17
|
+
import { r as releaseBuildSlot, t as acquireBuildSlot } from "./build-slots-D0b6sJyo.mjs";
|
|
18
|
+
import { c as ensureWorkspaceStorageSafely, d as noMetroMessage, f as noMetroRemedy, h as warmMetro, i as detectEntryFile, n as pickDevClientScheme, o as needsPrebuild, p as resolveMetroWithRetry, s as runPrebuild, t as devClientScheme, u as launchOutcomeRecord } from "./dev-client-RpvXxCXV.mjs";
|
|
19
|
+
import { a as statsProjectKey, i as recordRunStats, n as readRunEstimates, t as createRunRecorder } from "./stats-BCWEVLrM.mjs";
|
|
20
|
+
import { C as memoizeEmulatorProbe, L as waitForBoot, M as resetAdoptedAvd, N as resolveOwnedAvdSerial, P as resolvePhysicalDevice, _ as findBuildTool, a as androidSystemImageAbi, g as extractEmulatorFailure, h as emulatorFailureRemedy, i as androidPoolNoCandidatesRefusal, j as probeEmulatorSerial, k as physicalDeviceModel, m as emulatorDiskSpaceRemedy, n as androidHome, r as androidPoolCandidates, t as androidDeviceAbi, x as listInstalledSystemImages, y as listAdbDevices } from "./android-K63_0UfF.mjs";
|
|
21
|
+
import { C as unknownAndroidSystemImageRefusal, _ as AvdRecoveryError, b as ensureBooted, f as startBuildHeartbeat, p as tailLines, r as HEARTBEAT_INTERVAL_MS, v as checkDeviceCapacity, x as ensureOwnedDevice } from "./xcode-DeKCribl.mjs";
|
|
22
|
+
import { a as ensureMetroReachable, b as ownedSessionName, l as resolveRemoteContext, n as binOnPath, o as ensureRemoteBootOwned, s as remoteAndroidDeps } from "./device-remote-E81KAdXf.mjs";
|
|
23
|
+
import { t as cleanLine } from "./server-expo-C3ktAwUG.mjs";
|
|
24
|
+
import { a as buildAndroid, c as CCACHE_NOT_RUN, f as resolveCcache, l as CCACHE_UNAVAILABLE, n as resolveAndroidCas, o as productFlavorRefusal, p as formatDiagnostic, r as resolveAndroidCompilerCache, s as readProductFlavors, u as ccacheActivityLine } from "./android-cas-D6HPZ6UQ.mjs";
|
|
25
25
|
import { t as spawnEntry } from "./spawn-entry-nCE6m770.mjs";
|
|
26
|
-
import { a as printNativeCrashReport, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-
|
|
26
|
+
import { a as printNativeCrashReport, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-Dw8Gn3yw.mjs";
|
|
27
27
|
import { existsSync, mkdirSync, openSync, readFileSync, readdirSync, rmSync } from "node:fs";
|
|
28
28
|
import { InvalidArgumentError } from "commander";
|
|
29
29
|
import { basename, dirname, join, relative } from "node:path";
|
|
@@ -840,7 +840,7 @@ async function startCollector({ root, serial, packageName, spawn, kill, alive =
|
|
|
840
840
|
}
|
|
841
841
|
//#endregion
|
|
842
842
|
//#region src/commands/android/launch.ts
|
|
843
|
-
async function verifyAndroidRun({ root, release, remoteRelease, remoteDevice, verifyReleaseLaunched, verifyLaunched, serial, androidPackage, variant, metroCheck, logsDir, launchedAt, metroPort, isExpo, physical, scheme, component = null, phase }) {
|
|
843
|
+
async function verifyAndroidRun({ root, release, remoteRelease, remoteDevice, verifyReleaseLaunched, verifyLaunched, serial, androidPackage, variant, metroCheck, logsDir, launchedAt, metroPort, isExpo, physical, device, scheme, component = null, phase }) {
|
|
844
844
|
const readNativeCrashes = () => remoteDevice ? [] : captureNativeCrashes({
|
|
845
845
|
root,
|
|
846
846
|
platform: "android",
|
|
@@ -872,7 +872,12 @@ async function verifyAndroidRun({ root, release, remoteRelease, remoteDevice, ve
|
|
|
872
872
|
phase("", chalk.yellow("A release process exited before readiness. Run `stim logs --errors` for captured crash reports, or `stim logs --source device` for the full device output."));
|
|
873
873
|
return { state: LAUNCH_FATAL };
|
|
874
874
|
}
|
|
875
|
+
const newEmulator = Boolean(device.created && device.owned && !remoteDevice);
|
|
876
|
+
const timeoutMs = newEmulator ? 6e4 : VERIFY_TIMEOUT_MS;
|
|
877
|
+
if (metroCheck && newEmulator) phase("verify", "waiting up to 60s for bundle load (new emulator)");
|
|
875
878
|
const verification = metroCheck ? await verifyLaunched({
|
|
879
|
+
timeoutMs,
|
|
880
|
+
requireBundleResponse: true,
|
|
876
881
|
onReadinessPending: () => phase("readiness", "waiting for app readiness (up to 30s after bundle load)"),
|
|
877
882
|
logsDir,
|
|
878
883
|
since: launchedAt,
|
|
@@ -947,7 +952,29 @@ async function verifyAndroidRun({ root, release, remoteRelease, remoteDevice, ve
|
|
|
947
952
|
})) phase("", chalk.yellow(line));
|
|
948
953
|
return { state: LAUNCH_UNVERIFIED };
|
|
949
954
|
}
|
|
950
|
-
async function
|
|
955
|
+
async function resolveInstallSerial({ root, device, physical, remoteDevice, serial, resolveAvdSerial, waitForDeviceBoot, phase }) {
|
|
956
|
+
if (physical || remoteDevice || !device.owned || !device.avdName) return serial;
|
|
957
|
+
const resolved = resolveAvdSerial(device.avdName, { timeoutMs: 5e3 });
|
|
958
|
+
if (!resolved.serial) throw new Error(`Could not verify a running owned AVD ${device.avdName} before installation.`);
|
|
959
|
+
if (resolved.serial !== serial) {
|
|
960
|
+
phase("device", `${device.avdName} changed serial (${serial} -> ${resolved.serial}); checking readiness before installation`);
|
|
961
|
+
const ready = await waitForDeviceBoot(resolved.serial, 6e4, { commandTimeoutMs: 5e3 });
|
|
962
|
+
if (!ready.ok) throw new Error(`Emulator ${resolved.serial} never reported boot completion. Diagnostic: ${JSON.stringify(ready.diagnostic)}`);
|
|
963
|
+
if (resolveAvdSerial(device.avdName, { timeoutMs: 5e3 }).serial !== resolved.serial) throw new Error(`Could not verify AVD ${device.avdName} still runs on ${resolved.serial} after checking readiness.`);
|
|
964
|
+
phase("device", `reopen agent-device on ${resolved.serial}`);
|
|
965
|
+
}
|
|
966
|
+
const consolePort = Number(resolved.serial.replace(/^emulator-/, ""));
|
|
967
|
+
withConfigLock(() => {
|
|
968
|
+
const current = loadConfig()?.projects?.[root]?.platforms?.android;
|
|
969
|
+
if (!current?.owned || current.avdName !== device.avdName) throw new Error("The owned emulator assignment changed before installation.");
|
|
970
|
+
if (current.consolePort !== consolePort) setDevice(root, PLATFORM, {
|
|
971
|
+
...current,
|
|
972
|
+
consolePort
|
|
973
|
+
});
|
|
974
|
+
});
|
|
975
|
+
return resolved.serial;
|
|
976
|
+
}
|
|
977
|
+
async function finishAndroidRun({ lease, releaseLease, root, json, metroCheck, useBuildCache, variant, release, isExpo, metroPort, logsDir, emuLog, device, physical, remoteDevice, bootPromise, resolveAvdSerial, waitForDeviceBoot, bootDuration, apkPath, androidPackage: initialPackage, swapDir, record, waitedForBuild, ccache, uploadPending, providerUpload, providerName, remote, abandonedRemote: remoteWasAbandoned, started, startedAt, writer, phase, fail, readApkPackage, install, launch, launchRelease, resolveDevClientScheme, verifyLaunched, verifyReleaseLaunched, spawn, kill, pidAlive, verifyCollector, writeLaunch, writeState, now, out, emit, recordRun }) {
|
|
951
978
|
let androidPackage = initialPackage;
|
|
952
979
|
let leaseWarned = false;
|
|
953
980
|
const raiseLeaseFor = (boundMs, beforeInstall) => {
|
|
@@ -976,7 +1003,21 @@ async function finishAndroidRun({ lease, releaseLease, root, json, metroCheck, u
|
|
|
976
1003
|
logPath: diag.logPath ? displayPath(root, diag.logPath) : null
|
|
977
1004
|
});
|
|
978
1005
|
}
|
|
979
|
-
|
|
1006
|
+
let serial;
|
|
1007
|
+
try {
|
|
1008
|
+
serial = await resolveInstallSerial({
|
|
1009
|
+
root,
|
|
1010
|
+
device,
|
|
1011
|
+
physical,
|
|
1012
|
+
remoteDevice,
|
|
1013
|
+
serial: booted.serial,
|
|
1014
|
+
resolveAvdSerial,
|
|
1015
|
+
waitForDeviceBoot,
|
|
1016
|
+
phase
|
|
1017
|
+
});
|
|
1018
|
+
} catch (error) {
|
|
1019
|
+
return fail(NO_DEVICE, error instanceof Error ? error.message : String(error), "Run `stim status` to inspect the owned AVD, then retry `stim android`; the APK was not installed.");
|
|
1020
|
+
}
|
|
980
1021
|
phase("device", physical ? `${device.deviceName || serial} (${serial}) connected, not owned by Stim` : `${device.avdName || serial} (${serial}) ${device.adopted || device.adoptionPending ? "adopted" : "booted"} ${bootDuration()}`);
|
|
981
1022
|
const packageFromApk = readApkPackage(apkPath);
|
|
982
1023
|
if (packageFromApk && androidPackage && packageFromApk !== androidPackage) phase("install", chalk.dim(`applicationId ${packageFromApk} (from the APK; project files say ${androidPackage})`));
|
|
@@ -1159,6 +1200,7 @@ async function finishAndroidRun({ lease, releaseLease, root, json, metroCheck, u
|
|
|
1159
1200
|
metroPort,
|
|
1160
1201
|
isExpo,
|
|
1161
1202
|
physical,
|
|
1203
|
+
device,
|
|
1162
1204
|
scheme,
|
|
1163
1205
|
component: launched.component ?? null,
|
|
1164
1206
|
phase
|
|
@@ -1263,7 +1305,7 @@ function registerAndroid(program) {
|
|
|
1263
1305
|
})).ok) process.exit(1);
|
|
1264
1306
|
});
|
|
1265
1307
|
}
|
|
1266
|
-
function resolveRunAndroidOptions({ root, json = false, remoteDevice: commandRemoteBackend = null, resolveSettingsFor = resolveSettings, resolveRemoteDeviceContext = resolveRemoteContext, remoteDeviceDeps: makeRemoteDeviceDeps = remoteAndroidDeps, resolveEasBin = resolveEasCliBin, ensureMetroReachable: ensureRemoteMetro = ensureMetroReachable, ensureRemoteBootOwned: ensureRemoteOwned = ensureRemoteBootOwned, detectRemoteProviders = detectProviders, metroCheck = true, useBuildCache = true, variant: variantFlag = null, systemImage: systemImageFlag = null, device: deviceFlag = null, wait: waitFlag = void 0, waitConflict = false, acquireLease = acquireRunLease, makeRunLease = runLease, selectPool = selectFromPool, onLeaseSignal = releaseLeaseOnSignal, listDevices = listAdbDevices, deviceModel = physicalDeviceModel, deviceAbi = androidDeviceAbi, isEmulatorDevice = probeEmulatorSerial, readApkPackage = (apkPath) => apkPackage(dumpApkManifest(apkPath)), getLimits = getConcurrencyLimits, checkCapacity = checkDeviceCapacity, acquireSlot = acquireBuildSlot, releaseSlot = releaseBuildSlot, ensureDevice = ensureOwnedDevice, listSystemImages = listInstalledSystemImages, ensureDeviceBooted = ensureBooted, resolveMetro = resolveProjectMetro, resolveMetroRetrying = resolveMetroWithRetry, readState = readWorkspaceState, pidAlive = pidExists, verifyCollector = verifyCollectorOwnership, verifyLaunched = verifyLaunch, ensureStorage = ensureWorkspaceStorageSafely, fingerprint = fingerprintProject, untracked = untrackedNativeFiles, resolveCached = resolveBuild, storeCached = storeBuild, storedAssets = storedAssetManifest, captureAssets = captureAssetManifest, acquireLock = acquireBuildLock, releaseLock = releaseBuildLock, waitForBuild: waitForBuild$1 = waitForBuild, loadProvider = loadProjectProvider, easAuth = checkEasAuth, resolveRemoteBuild = resolveRemote, uploadRemoteBuild = uploadRemote, resolveCacheProvider = resolveCacheProviderConfig, loadCacheProviderModule = loadCacheProvider, needsPrebuildFor = needsPrebuild, prebuild = runPrebuild, build = buildAndroid, ccacheFor = resolveCcache, install = installAndroidApp, launch = launchAndroidApp, launchRelease = launchAndroidReleaseApp, verifyReleaseLaunched = verifyAndroidReleaseLaunch, swapApk = swapApkBundle, resolveDevClientScheme = androidDevClientScheme, spawn = (cmd, args, opts) => getExecutor().spawn(cmd, args, opts), kill = (pid, signal) => process.kill(pid, signal), createWriter = createNdjsonWriter, writeLaunch = writeWorkspaceLaunch, writeState = writeWorkspaceState, recordStats = recordRunStats, readEstimates = readRunEstimates, now = Date.now, out = (line) => console.error(line), emit = (line) => console.log(line) } = {}) {
|
|
1308
|
+
function resolveRunAndroidOptions({ root, json = false, remoteDevice: commandRemoteBackend = null, resolveSettingsFor = resolveSettings, resolveRemoteDeviceContext = resolveRemoteContext, remoteDeviceDeps: makeRemoteDeviceDeps = remoteAndroidDeps, resolveEasBin = resolveEasCliBin, ensureMetroReachable: ensureRemoteMetro = ensureMetroReachable, ensureRemoteBootOwned: ensureRemoteOwned = ensureRemoteBootOwned, detectRemoteProviders = detectProviders, metroCheck = true, useBuildCache = true, variant: variantFlag = null, systemImage: systemImageFlag = null, device: deviceFlag = null, wait: waitFlag = void 0, waitConflict = false, acquireLease = acquireRunLease, makeRunLease = runLease, selectPool = selectFromPool, onLeaseSignal = releaseLeaseOnSignal, listDevices = listAdbDevices, deviceModel = physicalDeviceModel, deviceAbi = androidDeviceAbi, isEmulatorDevice = probeEmulatorSerial, readApkPackage = (apkPath) => apkPackage(dumpApkManifest(apkPath)), getLimits = getConcurrencyLimits, checkCapacity = checkDeviceCapacity, acquireSlot = acquireBuildSlot, releaseSlot = releaseBuildSlot, ensureDevice = ensureOwnedDevice, listSystemImages = listInstalledSystemImages, ensureDeviceBooted = ensureBooted, resolveAvdSerial = resolveOwnedAvdSerial, waitForDeviceBoot = waitForBoot, resolveMetro = resolveProjectMetro, warmMetro: prewarmMetro = warmMetro, resolveMetroRetrying = resolveMetroWithRetry, readState = readWorkspaceState, pidAlive = pidExists, verifyCollector = verifyCollectorOwnership, verifyLaunched = verifyLaunch, ensureStorage = ensureWorkspaceStorageSafely, fingerprint = fingerprintProject, untracked = untrackedNativeFiles, resolveCached = resolveBuild, storeCached = storeBuild, storedAssets = storedAssetManifest, captureAssets = captureAssetManifest, acquireLock = acquireBuildLock, releaseLock = releaseBuildLock, waitForBuild: waitForBuild$1 = waitForBuild, loadProvider = loadProjectProvider, easAuth = checkEasAuth, resolveRemoteBuild = resolveRemote, uploadRemoteBuild = uploadRemote, resolveCacheProvider = resolveCacheProviderConfig, loadCacheProviderModule = loadCacheProvider, needsPrebuildFor = needsPrebuild, prebuild = runPrebuild, build = buildAndroid, ccacheFor = resolveCcache, install = installAndroidApp, launch = launchAndroidApp, launchRelease = launchAndroidReleaseApp, verifyReleaseLaunched = verifyAndroidReleaseLaunch, swapApk = swapApkBundle, resolveDevClientScheme = androidDevClientScheme, spawn = (cmd, args, opts) => getExecutor().spawn(cmd, args, opts), kill = (pid, signal) => process.kill(pid, signal), createWriter = createNdjsonWriter, writeLaunch = writeWorkspaceLaunch, writeState = writeWorkspaceState, recordStats = recordRunStats, readEstimates = readRunEstimates, now = Date.now, out = (line) => console.error(line), emit = (line) => console.log(line) } = {}) {
|
|
1267
1309
|
return {
|
|
1268
1310
|
root,
|
|
1269
1311
|
json,
|
|
@@ -1298,7 +1340,10 @@ function resolveRunAndroidOptions({ root, json = false, remoteDevice: commandRem
|
|
|
1298
1340
|
ensureDevice,
|
|
1299
1341
|
listSystemImages,
|
|
1300
1342
|
ensureDeviceBooted,
|
|
1343
|
+
resolveAvdSerial,
|
|
1344
|
+
waitForDeviceBoot,
|
|
1301
1345
|
resolveMetro,
|
|
1346
|
+
prewarmMetro,
|
|
1302
1347
|
resolveMetroRetrying,
|
|
1303
1348
|
readState,
|
|
1304
1349
|
pidAlive,
|
|
@@ -1343,7 +1388,7 @@ function resolveRunAndroidOptions({ root, json = false, remoteDevice: commandRem
|
|
|
1343
1388
|
};
|
|
1344
1389
|
}
|
|
1345
1390
|
async function runAndroid(options = {}) {
|
|
1346
|
-
let { root, json, commandRemoteBackend, resolveSettingsFor, resolveRemoteDeviceContext, makeRemoteDeviceDeps, resolveEasBin, ensureRemoteMetro, ensureRemoteOwned, detectRemoteProviders, metroCheck, useBuildCache: requestedBuildCache, variantFlag, systemImageFlag, deviceFlag, waitFlag, waitConflict, acquireLease, makeRunLease, selectPool, onLeaseSignal, listDevices, deviceModel, deviceAbi, isEmulatorDevice, readApkPackage, getLimits, checkCapacity, acquireSlot, releaseSlot, ensureDevice, listSystemImages, ensureDeviceBooted, resolveMetro, resolveMetroRetrying, readState, pidAlive, verifyCollector, verifyLaunched, ensureStorage, fingerprint, untracked, resolveCached, storeCached, storedAssets, captureAssets, acquireLock, releaseLock, waitForBuild, loadProvider, easAuth, resolveRemoteBuild, uploadRemoteBuild, resolveCacheProvider, loadCacheProviderModule, needsPrebuildFor, prebuild, build, ccacheFor, install, launch, launchRelease, verifyReleaseLaunched, swapApk, resolveDevClientScheme, spawn, kill, createWriter, writeLaunch, writeState, recordStats, readEstimates, now, out, emit } = resolveRunAndroidOptions(options);
|
|
1391
|
+
let { root, json, commandRemoteBackend, resolveSettingsFor, resolveRemoteDeviceContext, makeRemoteDeviceDeps, resolveEasBin, ensureRemoteMetro, ensureRemoteOwned, detectRemoteProviders, metroCheck, useBuildCache: requestedBuildCache, variantFlag, systemImageFlag, deviceFlag, waitFlag, waitConflict, acquireLease, makeRunLease, selectPool, onLeaseSignal, listDevices, deviceModel, deviceAbi, isEmulatorDevice, readApkPackage, getLimits, checkCapacity, acquireSlot, releaseSlot, ensureDevice, listSystemImages, ensureDeviceBooted, resolveAvdSerial, waitForDeviceBoot, resolveMetro, prewarmMetro, resolveMetroRetrying, readState, pidAlive, verifyCollector, verifyLaunched, ensureStorage, fingerprint, untracked, resolveCached, storeCached, storedAssets, captureAssets, acquireLock, releaseLock, waitForBuild, loadProvider, easAuth, resolveRemoteBuild, uploadRemoteBuild, resolveCacheProvider, loadCacheProviderModule, needsPrebuildFor, prebuild, build, ccacheFor, install, launch, launchRelease, verifyReleaseLaunched, swapApk, resolveDevClientScheme, spawn, kill, createWriter, writeLaunch, writeState, recordStats, readEstimates, now, out, emit } = resolveRunAndroidOptions(options);
|
|
1347
1392
|
const started = now();
|
|
1348
1393
|
const startedAt = new Date(started).toISOString();
|
|
1349
1394
|
const projectProblem = appProjectProblem(root);
|
|
@@ -1673,7 +1718,8 @@ async function runAndroid(options = {}) {
|
|
|
1673
1718
|
const diag = noDeviceDiagnostic({
|
|
1674
1719
|
reason: `Could not ensure an owned Android emulator: ${err?.message || err}`,
|
|
1675
1720
|
logFile: emuLog,
|
|
1676
|
-
|
|
1721
|
+
localEmulator: !(err instanceof AvdRecoveryError),
|
|
1722
|
+
remedy: err instanceof AvdRecoveryError ? err.remedy : "Check that JAVA_HOME and ANDROID_HOME are set correctly, and that an arm64 system image is installed (`sdkmanager \"system-images;android-36;google_apis;arm64-v8a\"`)."
|
|
1677
1723
|
});
|
|
1678
1724
|
return fail(NO_DEVICE, diag.message, diag.remedy, {
|
|
1679
1725
|
lines: diag.lines,
|
|
@@ -1825,6 +1871,13 @@ async function runAndroid(options = {}) {
|
|
|
1825
1871
|
return true;
|
|
1826
1872
|
}
|
|
1827
1873
|
const runFromFingerprint = async () => {
|
|
1874
|
+
if (metroCheck && metroPort !== null && optimizations.metroWarmup) prewarmMetro({
|
|
1875
|
+
port: metroPort,
|
|
1876
|
+
platform: "android",
|
|
1877
|
+
isExpo,
|
|
1878
|
+
appId: androidPackage,
|
|
1879
|
+
bundleUrl: metroWarmupUrlSetting(settings, "android")
|
|
1880
|
+
});
|
|
1828
1881
|
if (!await resolveInitialFingerprint()) return phaseFailure;
|
|
1829
1882
|
let remote = null;
|
|
1830
1883
|
let abandonedRemote = false;
|
|
@@ -1910,7 +1963,7 @@ async function runAndroid(options = {}) {
|
|
|
1910
1963
|
releasedWait = null;
|
|
1911
1964
|
const holder = attempt.held;
|
|
1912
1965
|
const who = holder.projectRoot || "another workspace";
|
|
1913
|
-
phase("build", `${who} is already building ${shortHash(hash)} (pid ${holder.pid})${holder.logFile ? ` -- tail ${holder.logFile}` : ""}`);
|
|
1966
|
+
phase("build", `${who} is already building ${shortHash(hash)} (pid ${holder.pid})${holder.logFile ? ` -- tail ${holder.logFile}` : ""} -- stim guide lifecycle concurrency`);
|
|
1914
1967
|
let waited = null;
|
|
1915
1968
|
try {
|
|
1916
1969
|
const ceilingMs = WAIT_CEILING_MS - (now() - waitStarted);
|
|
@@ -1942,7 +1995,7 @@ async function runAndroid(options = {}) {
|
|
|
1942
1995
|
pid: holder.pid,
|
|
1943
1996
|
ms: waited.waitedMs
|
|
1944
1997
|
};
|
|
1945
|
-
phase("build", `waited ${formatDuration(waited.waitedMs)} for ${who}'s build -> installed from cache`);
|
|
1998
|
+
phase("build", `waited ${formatDuration(waited.waitedMs)} for ${who}'s build -> installed from cache -- stim guide lifecycle concurrency`);
|
|
1946
1999
|
} else if (waited?.lockReleased) {
|
|
1947
2000
|
failedHolder = void 0;
|
|
1948
2001
|
releasedWait = {
|
|
@@ -2049,7 +2102,7 @@ async function runAndroid(options = {}) {
|
|
|
2049
2102
|
phase("cache", `hit ${shortHash(storeHash)} (post-prebuild key)`);
|
|
2050
2103
|
if (releasedWait) {
|
|
2051
2104
|
waitedForBuild = releasedWait.facts;
|
|
2052
|
-
phase("build", `waited ${formatDuration(waitedForBuild.ms)} for ${releasedWait.who}'s build -> installed from cache`);
|
|
2105
|
+
phase("build", `waited ${formatDuration(waitedForBuild.ms)} for ${releasedWait.who}'s build -> installed from cache -- stim guide lifecycle concurrency`);
|
|
2053
2106
|
}
|
|
2054
2107
|
}
|
|
2055
2108
|
}
|
|
@@ -2223,6 +2276,8 @@ async function runAndroid(options = {}) {
|
|
|
2223
2276
|
physical,
|
|
2224
2277
|
remoteDevice,
|
|
2225
2278
|
bootPromise,
|
|
2279
|
+
resolveAvdSerial,
|
|
2280
|
+
waitForDeviceBoot,
|
|
2226
2281
|
bootDuration: () => bootDuration,
|
|
2227
2282
|
apkPath,
|
|
2228
2283
|
androidPackage,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { r as pidExists } from "./metro-
|
|
3
|
-
import { c as androidDataPartitionSizeBytes } from "./settings-
|
|
4
|
-
import { existsSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
|
|
1
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
+
import { r as pidExists } from "./metro-COslRK_F.mjs";
|
|
3
|
+
import { c as androidDataPartitionSizeBytes } from "./settings-DwU1_U_q.mjs";
|
|
4
|
+
import { existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
|
|
5
5
|
import { homedir } from "os";
|
|
6
6
|
import { dirname, isAbsolute, join, resolve } from "path";
|
|
7
7
|
//#region src/sim/android.ts
|
|
@@ -11,6 +11,7 @@ const ANDROID_ABIS = /* @__PURE__ */ new Set([
|
|
|
11
11
|
"x86",
|
|
12
12
|
"x86_64"
|
|
13
13
|
]);
|
|
14
|
+
const DEFAULT_AVD_DEVICE = "pixel_6";
|
|
14
15
|
function androidHome() {
|
|
15
16
|
return process.env.ANDROID_HOME || process.env.ANDROID_SDK_ROOT || join(homedir(), "Library", "Android", "sdk");
|
|
16
17
|
}
|
|
@@ -115,7 +116,7 @@ function createOwnedAvd(label, { systemImage } = {}) {
|
|
|
115
116
|
throw new Error(`No ${arch} Android system image is installed. Install one, e.g.: sdkmanager "system-images;android-36;google_apis;${arch}"`);
|
|
116
117
|
}
|
|
117
118
|
const avdName = ownedAvdName(label);
|
|
118
|
-
getExecutor().run(`echo no | ${androidTool("avdmanager")} create avd -n "${avdName}" -k "${pick.pkg}"`);
|
|
119
|
+
getExecutor().run(`echo no | ${androidTool("avdmanager")} create avd -n "${avdName}" -k "${pick.pkg}" --device "${DEFAULT_AVD_DEVICE}"`);
|
|
119
120
|
return {
|
|
120
121
|
avdName,
|
|
121
122
|
systemImage: pick.pkg
|
|
@@ -334,6 +335,71 @@ function parseAvdRootIni(contents) {
|
|
|
334
335
|
relativePath
|
|
335
336
|
};
|
|
336
337
|
}
|
|
338
|
+
function avdIniPaths(root, ini) {
|
|
339
|
+
const parsed = parseAvdRootIni(ini);
|
|
340
|
+
return [parsed.relativePath && !isAbsolute(parsed.relativePath) ? resolve(dirname(root), parsed.relativePath) : null, parsed.path && isAbsolute(parsed.path) ? parsed.path : null].filter((candidate) => candidate !== null);
|
|
341
|
+
}
|
|
342
|
+
function avdStorageRoots() {
|
|
343
|
+
const env = process.env;
|
|
344
|
+
return [...new Set([
|
|
345
|
+
env.ANDROID_AVD_HOME,
|
|
346
|
+
env.ANDROID_EMULATOR_HOME ? join(env.ANDROID_EMULATOR_HOME, "avd") : null,
|
|
347
|
+
env.ANDROID_USER_HOME ? join(env.ANDROID_USER_HOME, "avd") : null,
|
|
348
|
+
env.ANDROID_SDK_HOME ? join(env.ANDROID_SDK_HOME, ".android", "avd") : null,
|
|
349
|
+
env.ANDROID_SDK_HOME ? join(env.ANDROID_SDK_HOME, "avd") : null,
|
|
350
|
+
join(homedir(), ".android", "avd")
|
|
351
|
+
].filter((value) => Boolean(value)))];
|
|
352
|
+
}
|
|
353
|
+
function avdPathExists(path) {
|
|
354
|
+
try {
|
|
355
|
+
lstatSync(path);
|
|
356
|
+
return true;
|
|
357
|
+
} catch (error) {
|
|
358
|
+
if (error.code === "ENOENT") return false;
|
|
359
|
+
throw error;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function listOrphanedAvdDirectories(avdName) {
|
|
363
|
+
const roots = avdStorageRoots();
|
|
364
|
+
const stores = roots.filter(avdPathExists).map((root) => ({
|
|
365
|
+
root,
|
|
366
|
+
canonicalRoot: realpathSync(root),
|
|
367
|
+
names: readdirSync(root)
|
|
368
|
+
}));
|
|
369
|
+
const registered = /* @__PURE__ */ new Set();
|
|
370
|
+
for (const { root, canonicalRoot, names } of stores) for (const name of names.filter((entry) => entry.endsWith(".ini"))) {
|
|
371
|
+
const path = join(root, name);
|
|
372
|
+
const ini = readFileSync(path, "utf8");
|
|
373
|
+
const targets = /* @__PURE__ */ new Set([...avdIniPaths(root, ini), ...avdIniPaths(canonicalRoot, ini)]);
|
|
374
|
+
if (!targets.size) throw new Error(`Cannot verify AVD registration at ${path}; its data was kept.`);
|
|
375
|
+
for (const target of targets) try {
|
|
376
|
+
registered.add(realpathSync(target));
|
|
377
|
+
} catch (error) {
|
|
378
|
+
const code = error.code;
|
|
379
|
+
if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
const orphaned = [];
|
|
383
|
+
for (const { canonicalRoot, names: entries } of stores) {
|
|
384
|
+
const names = avdName ? [`${avdName}.avd`] : entries;
|
|
385
|
+
for (const entry of names) {
|
|
386
|
+
if (!/^stim-[A-Za-z0-9._-]+\.avd$/.test(entry)) continue;
|
|
387
|
+
const name = entry.slice(0, -4);
|
|
388
|
+
if (roots.some((candidate) => avdPathExists(join(candidate, `${name}.ini`)))) continue;
|
|
389
|
+
const directory = join(canonicalRoot, entry);
|
|
390
|
+
if (registered.has(directory) || !avdPathExists(directory)) continue;
|
|
391
|
+
const stat = lstatSync(directory);
|
|
392
|
+
if (!stat.isDirectory() || stat.isSymbolicLink() || realpathSync(directory) !== directory) throw new Error(`Cannot verify AVD data at ${directory}; it was kept.`);
|
|
393
|
+
if (!orphaned.some((candidate) => candidate.directory === directory)) orphaned.push({
|
|
394
|
+
name,
|
|
395
|
+
directory,
|
|
396
|
+
dev: stat.dev,
|
|
397
|
+
ino: stat.ino
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return orphaned;
|
|
402
|
+
}
|
|
337
403
|
function ownedAvdDirectory(avdName, { env = process.env, home = homedir(), readFile = (path) => readFileSync(path, "utf8"), realpath = realpathSync, isDirectory = (path) => statSync(path).isDirectory() } = {}) {
|
|
338
404
|
if (!/^stim-[A-Za-z0-9._-]+$/.test(avdName)) return null;
|
|
339
405
|
const roots = [
|
|
@@ -350,15 +416,10 @@ function ownedAvdDirectory(avdName, { env = process.env, home = homedir(), readF
|
|
|
350
416
|
if (code === "ENOENT" || code === "ENOTDIR") continue;
|
|
351
417
|
return null;
|
|
352
418
|
}
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
try {
|
|
358
|
-
const canonical = realpath(candidate);
|
|
359
|
-
if (isDirectory(canonical)) return canonical;
|
|
360
|
-
} catch {}
|
|
361
|
-
}
|
|
419
|
+
for (const candidate of avdIniPaths(root, ini)) try {
|
|
420
|
+
const canonical = realpath(candidate);
|
|
421
|
+
if (isDirectory(canonical)) return canonical;
|
|
422
|
+
} catch {}
|
|
362
423
|
return null;
|
|
363
424
|
}
|
|
364
425
|
return null;
|
|
@@ -415,6 +476,7 @@ function configureNewOwnedAvd(avdName, { dataPartitionSizeGb, avdConfig = {} },
|
|
|
415
476
|
function avdPoolConfiguration(dataPartitionSizeGb, avdConfig) {
|
|
416
477
|
return JSON.stringify(Object.entries({
|
|
417
478
|
...avdConfig,
|
|
479
|
+
"hw.device.name": DEFAULT_AVD_DEVICE,
|
|
418
480
|
"disk.dataPartition.size": String(androidDataPartitionSizeBytes(dataPartitionSizeGb))
|
|
419
481
|
}).toSorted(([a], [b]) => a.localeCompare(b)));
|
|
420
482
|
}
|
|
@@ -662,4 +724,4 @@ function resolveOwnedAvdSerial(avdName, { timeoutMs } = {}) {
|
|
|
662
724
|
return { notRunning: true };
|
|
663
725
|
}
|
|
664
726
|
//#endregion
|
|
665
|
-
export {
|
|
727
|
+
export { pickDefaultSystemImage as A, memoizeEmulatorProbe as C, ownedAvdName as D, ownedAvdMatchesConfiguration as E, shutdownAndroidEmulator as F, waitForAndroidEmulatorShutdown as I, waitForBoot as L, resetAdoptedAvd as M, resolveOwnedAvdSerial as N, ownedAvdSystemImage as O, resolvePhysicalDevice as P, listOrphanedAvdDirectories as S, ownedAvdDirectory as T, findBuildTool as _, androidSystemImageAbi as a, listAvds as b, avdPoolConfiguration as c, configureNewOwnedAvd as d, createOwnedAvd as f, extractEmulatorFailure as g, emulatorFailureRemedy as h, androidPoolNoCandidatesRefusal as i, probeEmulatorSerial as j, physicalDeviceModel as k, avdStorageRoots as l, emulatorDiskSpaceRemedy as m, androidHome as n, assertOwnedAvdStopped as o, deleteAvd as p, androidPoolCandidates as r, avdPathExists as s, androidDeviceAbi as t, bootAndroidEmulator as u, getAvdNameForSerial as v, nextConsolePort as w, listInstalledSystemImages as x, listAdbDevices as y };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { k as withDirLock, u as getConfigDir } from "./config-
|
|
3
|
-
import { r as register } from "./cache-manifest-
|
|
4
|
-
import { D as workspaceLogsDir, x as sharedCcache, y as ensureWorkspaceStorage } from "./state-
|
|
1
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
+
import { k as withDirLock, u as getConfigDir } from "./config-CMtIaTk9.mjs";
|
|
3
|
+
import { r as register } from "./cache-manifest-Cu4_Znw9.mjs";
|
|
4
|
+
import { D as workspaceLogsDir, x as sharedCcache, y as ensureWorkspaceStorage } from "./state-CZ-ER-8d.mjs";
|
|
5
5
|
import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-C7IlIzd7.mjs";
|
|
6
6
|
import { l as phaseLine } from "./command-output-8wHMEde0.mjs";
|
|
7
|
-
import { n as androidHome } from "./android-
|
|
8
|
-
import { f as startBuildHeartbeat, r as HEARTBEAT_INTERVAL_MS } from "./xcode-
|
|
7
|
+
import { n as androidHome } from "./android-K63_0UfF.mjs";
|
|
8
|
+
import { f as startBuildHeartbeat, r as HEARTBEAT_INTERVAL_MS } from "./xcode-DeKCribl.mjs";
|
|
9
9
|
import { accessSync, constants, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { createHash, randomUUID } from "node:crypto";
|
|
11
11
|
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
3
3
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { createHash, randomUUID } from "node:crypto";
|
|
5
5
|
import { join } from "node:path";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
1
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
2
|
import { o as parseNdjsonText } from "./ndjson-DcAtEx_K.mjs";
|
|
3
|
-
import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-
|
|
3
|
+
import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-D3pzTKQE.mjs";
|
|
4
4
|
import { s as isAppLaunchError } from "./command-output-8wHMEde0.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { l as iosSimulatorFailureAdvice, p as listUserApps, w as uninstallIosApp } from "./ios-D1h1Di39.mjs";
|
|
6
6
|
import { closeSync, lstatSync, openSync, readFileSync, readSync, readdirSync } from "node:fs";
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
8
|
import { join } from "node:path";
|
|
@@ -157,6 +157,10 @@ const IOS_DEV_MENU_OFF_KEYS = ["EXDevMenuShowsAtLaunch", "EXDevMenuShowFloatingA
|
|
|
157
157
|
const DEV_CLIENT_ONBOARDING_QUERY = "disableOnboarding=1";
|
|
158
158
|
const DEV_CLIENT_DISABLE_FAB_QUERY = "disableFab=1";
|
|
159
159
|
const ANDROID_DISABLE_AUTO_LAUNCH_EXTRA = "EXDevMenuDisableAutoLaunch";
|
|
160
|
+
function describeIosSimulatorFailure(error, exec) {
|
|
161
|
+
const detail = describe(error);
|
|
162
|
+
return error?.code === "ETIMEDOUT" ? `${detail}. ${iosSimulatorFailureAdvice(exec)}` : detail;
|
|
163
|
+
}
|
|
160
164
|
function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null, proveInstalled = true }, { exec = null, now = null } = {}) {
|
|
161
165
|
const e = exec || getExecutor();
|
|
162
166
|
const artifactStartedAt = now?.();
|
|
@@ -171,12 +175,15 @@ function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null,
|
|
|
171
175
|
"install",
|
|
172
176
|
udid,
|
|
173
177
|
appPath
|
|
174
|
-
]
|
|
178
|
+
], {
|
|
179
|
+
timeoutMs: 3e5,
|
|
180
|
+
killSignal: "SIGKILL"
|
|
181
|
+
});
|
|
175
182
|
} catch (err) {
|
|
176
183
|
return {
|
|
177
184
|
failed: true,
|
|
178
185
|
code: INSTALL_ERROR,
|
|
179
|
-
reason: `simctl install failed for ${appPath}: ${
|
|
186
|
+
reason: `simctl install failed for ${appPath}: ${describeIosSimulatorFailure(err, e)}`
|
|
180
187
|
};
|
|
181
188
|
}
|
|
182
189
|
const artifactFinishedAt = now?.();
|
|
@@ -193,7 +200,7 @@ function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null,
|
|
|
193
200
|
key,
|
|
194
201
|
"-bool",
|
|
195
202
|
"false"
|
|
196
|
-
]);
|
|
203
|
+
], { timeoutMs: 6e4 });
|
|
197
204
|
for (const key of iosSchemeApprovalKeys(bundleId, devClientScheme)) e.runFile("xcrun", [
|
|
198
205
|
"simctl",
|
|
199
206
|
"spawn",
|
|
@@ -204,12 +211,12 @@ function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null,
|
|
|
204
211
|
key,
|
|
205
212
|
"-string",
|
|
206
213
|
bundleId
|
|
207
|
-
]);
|
|
214
|
+
], { timeoutMs: 6e4 });
|
|
208
215
|
} catch (err) {
|
|
209
216
|
return {
|
|
210
217
|
failed: true,
|
|
211
218
|
code: INSTALL_ERROR,
|
|
212
|
-
reason: `Installed ${bundleId}, but could not prepare the dev client: ${
|
|
219
|
+
reason: `Installed ${bundleId}, but could not prepare the dev client: ${describeIosSimulatorFailure(err, e)}`
|
|
213
220
|
};
|
|
214
221
|
}
|
|
215
222
|
const devClientPreparationDurationMs = now && preparationStartedAt !== void 0 ? now() - preparationStartedAt : void 0;
|
|
@@ -318,12 +325,12 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
318
325
|
bundleId,
|
|
319
326
|
"RCT_jsLocation",
|
|
320
327
|
jsLocationValue(metroPort)
|
|
321
|
-
]);
|
|
328
|
+
], { timeoutMs: 6e4 });
|
|
322
329
|
} catch (err) {
|
|
323
330
|
return {
|
|
324
331
|
failed: true,
|
|
325
332
|
code: LAUNCH_ERROR,
|
|
326
|
-
reason: `Could not point ${bundleId} at Metro port ${metroPort} (defaults write RCT_jsLocation): ${
|
|
333
|
+
reason: `Could not point ${bundleId} at Metro port ${metroPort} (defaults write RCT_jsLocation): ${describeIosSimulatorFailure(err, e)}`
|
|
327
334
|
};
|
|
328
335
|
}
|
|
329
336
|
if (devClientScheme) {
|
|
@@ -349,7 +356,7 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
349
356
|
"openurl",
|
|
350
357
|
udid,
|
|
351
358
|
url
|
|
352
|
-
]);
|
|
359
|
+
], { timeoutMs: 6e4 });
|
|
353
360
|
return {
|
|
354
361
|
ok: true,
|
|
355
362
|
mode: "openurl",
|
|
@@ -360,7 +367,7 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
360
367
|
return {
|
|
361
368
|
failed: true,
|
|
362
369
|
code: LAUNCH_ERROR,
|
|
363
|
-
reason: `simctl openurl ${url} failed: ${
|
|
370
|
+
reason: `simctl openurl ${url} failed: ${describeIosSimulatorFailure(err, e)}`
|
|
364
371
|
};
|
|
365
372
|
}
|
|
366
373
|
}
|
|
@@ -377,7 +384,7 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
377
384
|
return {
|
|
378
385
|
failed: true,
|
|
379
386
|
code: LAUNCH_ERROR,
|
|
380
|
-
reason: `simctl launch ${bundleId} failed: ${
|
|
387
|
+
reason: `simctl launch ${bundleId} failed: ${describeIosSimulatorFailure(err, e)}`
|
|
381
388
|
};
|
|
382
389
|
}
|
|
383
390
|
}
|
|
@@ -893,7 +900,7 @@ function nativeLaunchFailure({ readCrashes, since, platform, processAlive, mode,
|
|
|
893
900
|
waitedMs
|
|
894
901
|
} : null;
|
|
895
902
|
}
|
|
896
|
-
async function verifyLaunch({ logsDir, since, metroPort = null, platform = null, mode = null, timeoutMs = VERIFY_TIMEOUT_MS, stabilityMs = STABILITY_WINDOW_MS, pollMs = VERIFY_POLL_MS, readRecords = null, readDeviceRecords = null, readClientRecords = null, readNativeCrashes = null, processAlive = null, onReadinessPending = null, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)) } = {}) {
|
|
903
|
+
async function verifyLaunch({ logsDir, since, metroPort = null, platform = null, mode = null, requireBundleResponse, timeoutMs = VERIFY_TIMEOUT_MS, stabilityMs = STABILITY_WINDOW_MS, pollMs = VERIFY_POLL_MS, readRecords = null, readDeviceRecords = null, readClientRecords = null, readNativeCrashes = null, processAlive = null, onReadinessPending = null, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)) } = {}) {
|
|
897
904
|
const read = readRecords || (() => readMetroRecords(logsDir));
|
|
898
905
|
const readDevice = readDeviceRecords || (() => readNdjson(logsDir, "device.ndjson"));
|
|
899
906
|
const readClient = readClientRecords || (() => readNdjson(logsDir, "client.ndjson"));
|
|
@@ -909,6 +916,7 @@ async function verifyLaunch({ logsDir, since, metroPort = null, platform = null,
|
|
|
909
916
|
let nextCrashCheck = startedAt + 1e3;
|
|
910
917
|
while (true) {
|
|
911
918
|
const metroRecords = read().filter((record) => after(record, since));
|
|
919
|
+
const bundleRecords = metroRecords.filter((record) => !requireBundleResponse || String(record.event).startsWith("bundle_response_"));
|
|
912
920
|
const deviceRecords = readDevice().filter((record) => after(record, since));
|
|
913
921
|
const clientRecords = readClient().filter((record) => after(record, since));
|
|
914
922
|
if (now() >= nextCrashCheck) {
|
|
@@ -924,14 +932,14 @@ async function verifyLaunch({ logsDir, since, metroPort = null, platform = null,
|
|
|
924
932
|
if (crash) return crash;
|
|
925
933
|
}
|
|
926
934
|
if (deliveryId === null) {
|
|
927
|
-
const request =
|
|
935
|
+
const request = bundleRecords.find((record) => record.event === "bundle_response_started" && typeof record.requestId === "string" && isBundleProof(record, since, platform));
|
|
928
936
|
if (request) {
|
|
929
937
|
deliveryId = request.requestId;
|
|
930
938
|
proof = null;
|
|
931
939
|
stabilityDeadline = null;
|
|
932
940
|
}
|
|
933
941
|
}
|
|
934
|
-
for (const record of
|
|
942
|
+
for (const record of bundleRecords) {
|
|
935
943
|
if (isBundleProof(record, since, platform)) activity = record;
|
|
936
944
|
const completed = deliveryId === null ? isBundleReadyProof(record, since, platform) : record.event === "bundle_response_finished" && record.requestId === deliveryId && isBundleProof(record, since, platform);
|
|
937
945
|
if (!proof && completed) {
|
|
@@ -960,7 +968,7 @@ async function verifyLaunch({ logsDir, since, metroPort = null, platform = null,
|
|
|
960
968
|
}
|
|
961
969
|
}
|
|
962
970
|
const ready = pendingAt !== null && signals.some((record) => Number(record.ts) >= pendingAt && Number(record.ts) <= readinessDeadline && appReadinessSignal(record, platform) === "ready");
|
|
963
|
-
const bundleErrors =
|
|
971
|
+
const bundleErrors = bundleRecords.filter((record) => isFatalLaunchError(record, platform) || deliveryId !== null && record.event === "bundle_response_failed" && record.requestId === deliveryId && isBundleProof(record, since, platform));
|
|
964
972
|
if (bundleErrors.length) {
|
|
965
973
|
const alive = processAlive ? processAlive() : null;
|
|
966
974
|
const fatalRecord = bundleErrors[bundleErrors.length - 1];
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { u as getConfigDir } from "./config-
|
|
3
|
-
import { r as register } from "./cache-manifest-
|
|
4
|
-
import { b as sharedBuildCache } from "./state-
|
|
1
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
+
import { u as getConfigDir } from "./config-CMtIaTk9.mjs";
|
|
3
|
+
import { r as register } from "./cache-manifest-Cu4_Znw9.mjs";
|
|
4
|
+
import { b as sharedBuildCache } from "./state-CZ-ER-8d.mjs";
|
|
5
5
|
import { a as formatElapsed } from "./command-output-8wHMEde0.mjs";
|
|
6
|
-
import { d as readClaimSet, f as releaseClaim, h as tryAcquireClaim, i as claimRemoveCommand, n as ClaimRefusedError } from "./ownership-claim-
|
|
6
|
+
import { d as readClaimSet, f as releaseClaim, h as tryAcquireClaim, i as claimRemoveCommand, n as ClaimRefusedError } from "./ownership-claim-7zRxxTfZ.mjs";
|
|
7
7
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
import { join } from "node:path";
|
|
@@ -578,7 +578,7 @@ function listBuildLocks() {
|
|
|
578
578
|
function waitingLine({ projectRoot, pid, elapsedMs, logFile }) {
|
|
579
579
|
const where = projectRoot || "another workspace";
|
|
580
580
|
const tail = logFile ? ` -- tail ${logFile}` : "";
|
|
581
|
-
return `${"build".padEnd(11)} waiting on ${where} (pid ${pid ?? "?"}, ${formatElapsed(elapsedMs)} elapsed)${tail}`;
|
|
581
|
+
return `${"build".padEnd(11)} waiting on ${where} (pid ${pid ?? "?"}, ${formatElapsed(elapsedMs)} elapsed)${tail} -- stim guide lifecycle concurrency`;
|
|
582
582
|
}
|
|
583
583
|
function takeoverLine({ projectRoot, pid, logFile, startedAt = null, now = Date.now }) {
|
|
584
584
|
const where = projectRoot || "another workspace";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { u as getConfigDir } from "./config-
|
|
1
|
+
import { u as getConfigDir } from "./config-CMtIaTk9.mjs";
|
|
2
2
|
import { a as formatElapsed } from "./command-output-8wHMEde0.mjs";
|
|
3
|
-
import { d as readClaimSet, f as releaseClaim, h as tryAcquireClaim, s as isClaimRefusal } from "./ownership-claim-
|
|
3
|
+
import { d as readClaimSet, f as releaseClaim, h as tryAcquireClaim, s as isClaimRefusal } from "./ownership-claim-7zRxxTfZ.mjs";
|
|
4
4
|
import { readdirSync, statSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
//#region src/engine/build-slots.ts
|
|
@@ -77,7 +77,7 @@ function tryAcquireBuildSlot({ max, root = null, logFile = null }) {
|
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
79
79
|
function slotWaitingLine({ max, elapsedMs }) {
|
|
80
|
-
return `${"build".padEnd(11)} waiting for a build slot (all ${max} in use, ${formatElapsed(elapsedMs)} elapsed)`;
|
|
80
|
+
return `${"build".padEnd(11)} waiting for a build slot (all ${max} in use, ${formatElapsed(elapsedMs)} elapsed) -- stim guide lifecycle concurrency`;
|
|
81
81
|
}
|
|
82
82
|
async function acquireBuildSlot({ max, root = null, logFile = null, now = Date.now, out = () => {}, sleep = sleepAsync, intervalMs = SLOT_POLL_MS, progressMs = SLOT_PROGRESS_MS, ceilingMs = SLOT_CEILING_MS }) {
|
|
83
83
|
if (!max || max <= 0) return {
|