stim 1.17.0 → 1.17.1
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/{android--GorydsK.mjs → android-B6rDWrTm.mjs} +15 -15
- package/dist/{budget-DM984mnd.mjs → budget-CUDz870h.mjs} +30 -9
- package/dist/{build-plan-CmQCoyT-.mjs → build-plan-BJSXzsCL.mjs} +14 -14
- package/dist/{idle-B2m-Ovod.mjs → build-progress-D0WkjCPd.mjs} +56 -183
- package/dist/{cli-Daxug5-K.mjs → cli-BLQqDGlX.mjs} +13 -13
- package/dist/cli.mjs +1 -1
- package/dist/{machines-C2XiNwh9.mjs → client-CxNotugx.mjs} +314 -303
- package/dist/{deps-DNWaQs4V.mjs → deps-CVxlsRFn.mjs} +1 -1
- package/dist/{device-capacity-D0GWHnTM.mjs → device-capacity-ZC4XSZ4R.mjs} +2 -2
- package/dist/device-host-worker.mjs +3 -3
- package/dist/{device-ios-Bc7vbGwl.mjs → device-ios-C2Um-XUR.mjs} +1 -1
- package/dist/{doctor-Cnk9d7Hm.mjs → doctor-BF_435OC.mjs} +14 -13
- package/dist/{gc-DxCL2A46.mjs → gc-BsWKa_-d.mjs} +9 -8
- package/dist/{gradle-D7-L2Th3.mjs → gradle-bsBRy6i9.mjs} +1 -1
- package/dist/{guide-DjrTQGik.mjs → guide-DC3n6-NH.mjs} +134 -110
- package/dist/{hosted-android-DwLS4Mse.mjs → hosted-android-DgU31wY3.mjs} +3 -3
- package/dist/{hosted-client-wk1W_CNW.mjs → hosted-client-CdSoH-G6.mjs} +4 -4
- package/dist/{hosted-ios-aMo7Cljf.mjs → hosted-ios-BTaVj4Jb.mjs} +1 -1
- package/dist/{hosted-logs-DqYmWtXc.mjs → hosted-logs-SxfBvSvc.mjs} +2 -2
- package/dist/{hosted-macos-dlHXEeF5.mjs → hosted-macos-CT9E3meL.mjs} +2 -2
- package/dist/{hosted-native-C9xJ9rpA.mjs → hosted-native-CZLOrMrN.mjs} +3 -3
- package/dist/idle-BXG__1BA.mjs +176 -0
- package/dist/{idle-shutdown-_3oOV1V_.mjs → idle-shutdown-IGyNV8Cr.mjs} +1 -1
- package/dist/{ios-DE6duQoz.mjs → ios-C7JuT1bI.mjs} +18 -18
- package/dist/{logs-DUoKlDoS.mjs → logs-DNxKcok9.mjs} +3 -3
- package/dist/{macos-32po3kUq.mjs → macos-BEs8cwKx.mjs} +66 -25
- package/dist/maintenance-run.mjs +2 -2
- package/dist/{metro-gateway-DmslUM30.mjs → metro-gateway-CHqK0p-a.mjs} +1 -1
- package/dist/{native-runtime-DhJI3IVQ.mjs → native-runtime-YhaSxP4v.mjs} +1 -1
- package/dist/offload-worker.mjs +5 -5
- package/dist/{preview-CxPRIEht.mjs → preview-C_JjkEy4.mjs} +1 -1
- package/dist/{reload-qZei6iWn.mjs → reload-byOjE3P4.mjs} +2 -2
- package/dist/settings.schema.json +84 -66
- package/dist/{start-BopZcr4n.mjs → start-BEP-XmEA.mjs} +1 -1
- package/dist/{start-uee1wWjY.mjs → start-BHIersSm.mjs} +1 -1
- package/dist/{status-dXX2JX1C.mjs → status-CqeWbIWW.mjs} +8 -8
- package/dist/{stop-BjizrQwv.mjs → stop-Cj01je8D.mjs} +3 -3
- package/dist/{stop-Cr1d8DSE.mjs → stop-D03prQnW.mjs} +1 -1
- package/dist/{stop-BCwvvs7F.mjs → stop-DOxwkH4j.mjs} +1 -1
- package/dist/supervisor-run.mjs +4 -4
- package/dist/{support-BJPgYCu-.mjs → support-BE-tbOP9.mjs} +4 -4
- package/dist/{support-F9-sr0Oi.mjs → support-WvD__tSV.mjs} +2 -2
- package/dist/{toolchain-CNIBTIOv.mjs → toolchain-CdrxgUeA.mjs} +1 -1
- package/dist/{web-exQtGkoc.mjs → web-DddUdJzr.mjs} +2 -2
- package/dist/{worktree-ZpZR3S1k.mjs → worktree-AK_m-d_m.mjs} +6 -6
- package/dist/{worktree-Dc98cE6_.mjs → worktree-CsAjSmEo.mjs} +1 -1
- package/package.json +5 -5
|
@@ -7,38 +7,38 @@ import { B as settingsLayers, C as metroWarmupUrlSetting, F as settingFile, G as
|
|
|
7
7
|
import { d as projectShortcut, n as appProjectProblem, r as detectIsExpo, s as findProjectRoot$1, t as NO_PROJECT_REFUSAL } from "./project-D47Rh0ly.mjs";
|
|
8
8
|
import { l as resolveProjectMetro, o as pidExists, u as signalProcessTree } from "./metro-g8NqiJp-.mjs";
|
|
9
9
|
import { c as writeWorkspaceState, g as workspaceAgentDeviceDir, i as recordWorkspaceUse, l as emulatorLogFile, r as readWorkspaceState$1, v as workspaceDir, x as workspaceLogsDir$1 } from "./workspace-state-DqcCbpE7.mjs";
|
|
10
|
-
import { t as budgetGate } from "./budget-
|
|
10
|
+
import { t as budgetGate } from "./budget-CUDz870h.mjs";
|
|
11
11
|
import { A as providerDownloadPath, B as captureAssetManifest, D as fingerprintProject, E as fingerprintDiffRecord, F as storedAssetManifest, H as readAssetManifest, L as untrackedMissLine, M as refingerprintAfterMutation, N as resolveBuild, O as inputsChangedDuringBuild, P as storeBuild, R as untrackedNativeFiles, S as configInputsChanged, T as filesystemBuildCapability, V as compareAssetManifests, _ as waitForBuild, b as buildCacheKey, g as releaseBuildLock, j as providerUploadOutcome, k as prepareProviderDownloadDir, m as acquireBuildLock, v as waitForSharedBuild, x as changedDuringBuildLine, z as assetDiffReason } from "./device-lease-DpoS36_u.mjs";
|
|
12
12
|
import { r as releaseBuildSlot, t as acquireBuildSlot } from "./build-slots-41v_d2x9.mjs";
|
|
13
13
|
import { m as writeWorkspaceLaunch, n as MODE_EXPO, t as MODE_BARE } from "./state-BKa8wNN5.mjs";
|
|
14
14
|
import { $ as trimAndroidCaches, A as listAvds, B as ownedAvdSystemImage, D as hostSystemImageArch, F as ownedAvdDeviceProfile, G as probeEmulatorSerial, I as ownedAvdDirectory, J as resolveOwnedAvdSerial, K as profileNeedsFoldFeature, O as listAdbDevices, Q as systemImageSupportsFold, T as findBuildTool, U as physicalDeviceModel, W as pickDefaultSystemImage, Y as resolvePhysicalDevice, a as androidDeviceAbi, ft as parkedMaxSetting, i as androidDataFreeBytes, j as listInstalledSystemImages, k as listAvdDeviceProfiles, q as resetAdoptedAvd, r as androidBuildToolName, rt as configuredAndroidEmulatorApp, t as DEFAULT_AVD_DEVICE_PROFILE, tt as waitForBoot, u as androidToolCwd } from "./android-B_YNZy61.mjs";
|
|
15
15
|
import { a as workspaceLinks, i as workspaceLinkLine } from "./stim-desktop-Cnz8CPnl.mjs";
|
|
16
16
|
import { m as teardownOwnedAvd } from "./ownership-BMLqyBgJ.mjs";
|
|
17
|
-
import {
|
|
17
|
+
import { _ as statsProjectKey$1, c as recordFinishedBuild, d as createRunRecorder, f as readRunEstimates, g as recordRunStats, l as startBuildProgress, m as recordCapacityRefusal, n as NO_BUILD_PROGRESS, u as tapBuildLog } from "./build-progress-D0WkjCPd.mjs";
|
|
18
18
|
import { r as createNdjsonWriter } from "./ndjson-PclOIwVY.mjs";
|
|
19
|
-
import { E as ccacheActivityLine, T as CCACHE_UNAVAILABLE, b as tailLines, k as resolveCcache, n as androidToolchain, t as androidRequirements, u as HEARTBEAT_INTERVAL_MS, w as CCACHE_NOT_RUN, y as startBuildHeartbeat } from "./toolchain-
|
|
19
|
+
import { E as ccacheActivityLine, T as CCACHE_UNAVAILABLE, b as tailLines, k as resolveCcache, n as androidToolchain, t as androidRequirements, u as HEARTBEAT_INTERVAL_MS, w as CCACHE_NOT_RUN, y as startBuildHeartbeat } from "./toolchain-CdrxgUeA.mjs";
|
|
20
20
|
import { t as cleanLine } from "./server-expo-CHTyXD0G.mjs";
|
|
21
|
-
import {
|
|
22
|
-
import { r as hostedMetroSettings } from "./metro-gateway-
|
|
21
|
+
import { a as offloadBuild, c as placementLoad, d as OffloadRefusal, f as namedBuildMachine, h as resolveBuildPlacement, i as closeOffload, l as remotePhaseText, n as buildPlacementCandidates, p as parseBuildMachineOption, r as chooseBuildMachine, s as offloadPlacement } from "./client-CxNotugx.mjs";
|
|
22
|
+
import { r as hostedMetroSettings } from "./metro-gateway-CHqK0p-a.mjs";
|
|
23
23
|
import { n as verifyCollectorOwnership, r as readCollectors } from "./ownership-DyRQru0q.mjs";
|
|
24
|
-
import { n as DeviceAdmissionRefusal, r as checkDeviceCapacity, t as DEFAULT_DEVICE_SLOT_WAIT_MS } from "./device-capacity-
|
|
24
|
+
import { n as DeviceAdmissionRefusal, r as checkDeviceCapacity, t as DEFAULT_DEVICE_SLOT_WAIT_MS } from "./device-capacity-ZC4XSZ4R.mjs";
|
|
25
25
|
import { S as restartedAppNote, b as launchAndroidReleaseApp, c as androidDevClientUrl, g as installConflictKind, h as installAndroidApp, r as DEFAULT_METRO_PORT, s as androidAppProcess, t as ADB_INSTALL_TIMEOUT_MS, y as launchAndroidApp } from "./app-install-VPkI5WEg.mjs";
|
|
26
|
-
import { C as resolveSystemImage, S as resolveDeviceProfile, T as systemImageRefusal, _ as isReleaseVariant, a as PLATFORM, b as pooledAndroidDevice, c as androidSystemImageSetting, d as apkPackage, f as deviceProfileRefusal, g as foldableImageRefusal, h as findAapt, i as NO_FINGERPRINT, l as androidVariantSetting, m as dumpApkManifest, n as LAUNCH_FAILED, o as androidBuildOptions, p as displayPath, r as NO_DEVICE, s as androidDevClientScheme, t as INSTALL_FAILED, u as apkDevClientFacts, v as noDeviceDiagnostic, w as resolveVariant, x as remoteAvdFlagRefusal, y as parseXmltree } from "./support-
|
|
26
|
+
import { C as resolveSystemImage, S as resolveDeviceProfile, T as systemImageRefusal, _ as isReleaseVariant, a as PLATFORM, b as pooledAndroidDevice, c as androidSystemImageSetting, d as apkPackage, f as deviceProfileRefusal, g as foldableImageRefusal, h as findAapt, i as NO_FINGERPRINT, l as androidVariantSetting, m as dumpApkManifest, n as LAUNCH_FAILED, o as androidBuildOptions, p as displayPath, r as NO_DEVICE, s as androidDevClientScheme, t as INSTALL_FAILED, u as apkDevClientFacts, v as noDeviceDiagnostic, w as resolveVariant, x as remoteAvdFlagRefusal, y as parseXmltree } from "./support-WvD__tSV.mjs";
|
|
27
27
|
import { t as spawnEntry } from "./spawn-entry-jw19m8Nl.mjs";
|
|
28
28
|
import { i as staleNativeDirRefusal, n as recordPrebuild, r as runPrebuild, t as planPrebuild } from "./prebuild-D7RUMkwN.mjs";
|
|
29
|
-
import { c as formatDiagnostic, i as buildAndroid, o as productFlavorRefusal, s as readProductFlavors } from "./gradle-
|
|
29
|
+
import { c as formatDiagnostic, i as buildAndroid, o as productFlavorRefusal, s as readProductFlavors } from "./gradle-bsBRy6i9.mjs";
|
|
30
30
|
import { a as VERIFY_TIMEOUT_MS, d as verifyAndroidReleaseLaunch, f as verifyLaunch, i as RELEASE_VERIFY_WAIT_MS, l as unattributedLaunchLines, n as LAUNCH_FATAL, r as LAUNCH_UNVERIFIED, t as LAUNCH_BUNDLING, u as unverifiedLaunchLines } from "./launch-verify-lTnWZikR.mjs";
|
|
31
31
|
import { a as acquireRunLease, c as lostRefusal, d as runLease, f as waitFlagConflict, l as parseDeviceWait, o as leaseExpiryText, s as lostLine, t as DEBUG_VERIFY_STEP_MS, u as releaseLeaseOnSignal } from "./device-lease-run-B8YltIH_.mjs";
|
|
32
32
|
import { a as writeHostedAndroid, i as writeDevicePlacement, t as readHostedAndroid } from "./ios-state-8L3lgum6.mjs";
|
|
33
|
-
import { _ as AvdRecoveryError, a as refusePlan, b as devicePlacementLine, c as skippedMissReason, d as refreshUpdatesManifestFile, g as AvdBootError, h as ensureOwnedDevice, i as printPlan, l as UPDATES_MANIFEST_NAME, m as ensureBooted, n as planFlagRefusal, o as explainBuildMiss, p as didSetUpDevice, r as planPayload, s as fingerprintErrorMissReason, t as planCachedBuild, u as detectEntryFile, v as warmMetro, y as automaticDevicePlacement } from "./build-plan-
|
|
34
|
-
import { n as prepareHostedAndroid, t as placeHostedAndroid } from "./hosted-android-
|
|
33
|
+
import { _ as AvdRecoveryError, a as refusePlan, b as devicePlacementLine, c as skippedMissReason, d as refreshUpdatesManifestFile, g as AvdBootError, h as ensureOwnedDevice, i as printPlan, l as UPDATES_MANIFEST_NAME, m as ensureBooted, n as planFlagRefusal, o as explainBuildMiss, p as didSetUpDevice, r as planPayload, s as fingerprintErrorMissReason, t as planCachedBuild, u as detectEntryFile, v as warmMetro, y as automaticDevicePlacement } from "./build-plan-BJSXzsCL.mjs";
|
|
34
|
+
import { n as prepareHostedAndroid, t as placeHostedAndroid } from "./hosted-android-DgU31wY3.mjs";
|
|
35
35
|
import { n as nativeRunCommand, r as siblingPlatformSlots, t as launchSlotScope } from "./slot-launch-DmjBmpQV.mjs";
|
|
36
36
|
import { a as easAuthNote, c as loadProjectProvider, f as resolveEasCliBin, i as checkEasAuth, m as uploadRemote, n as UPLOAD_TIMEOUT_MS, o as exitAfterFlush, p as resolveRemote, r as cacheLevel, s as isEasAuthFailureText, t as RESOLVE_TIMEOUT_MS } from "./remote-cache-Ci4DQYYj.mjs";
|
|
37
37
|
import { a as ensureMetroReachable, c as remoteAndroidDeps, n as binOnPath, o as ensureRemoteBootOwned, u as resolveRemoteContext, w as ownedSessionName } from "./device-remote-hFSkpfQu.mjs";
|
|
38
38
|
import { d as runCancellationSignal, f as withNativeBuildRun, r as cancelledFailure, u as runCancellation } from "./native-run-D1Q56rAD.mjs";
|
|
39
39
|
import { a as isEasBuildFailure, o as planEasDevelopmentBuild, s as resolveEasDevelopmentBuild } from "./simslim-BWNrc3M3.mjs";
|
|
40
|
-
import { c as startDevServer, m as detectAppIds, p as detectAndroidPackage } from "./start-
|
|
41
|
-
import { i as launchOutcomeRecord, n as ensureWorkspaceStorageSafely, r as isPhysicalDeviceRequest, t as ensureDevServer } from "./native-runtime-
|
|
40
|
+
import { c as startDevServer, m as detectAppIds, p as detectAndroidPackage } from "./start-BHIersSm.mjs";
|
|
41
|
+
import { i as launchOutcomeRecord, n as ensureWorkspaceStorageSafely, r as isPhysicalDeviceRequest, t as ensureDevServer } from "./native-runtime-YhaSxP4v.mjs";
|
|
42
42
|
import { t as selectFromPool } from "./device-pool-3o7s5lo4.mjs";
|
|
43
43
|
import { a as printNativeCrashReport, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-C-NMnhrk.mjs";
|
|
44
44
|
import { n as resolveAndroidCas, r as resolveAndroidCompilerCache } from "./android-cas-ZFpjJBL_.mjs";
|
|
@@ -806,7 +806,7 @@ function fail$1(code, message, remedy, extra = {}) {
|
|
|
806
806
|
async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo, device, physical, hostedAbi, remote: remoteTarget, buildPlan, cacheProviderConfig, requestedBuildCache, easBuild, androidPackage: initialPackage, record, maxBuilds, progress }, { deviceAbi, fingerprint, untracked, resolveCached, storeCached, storedAssets, captureAssets, acquireLock, releaseLock, waitForBuild, loadProvider, easAuth, resolveRemoteBuild, uploadRemoteBuild, loadCacheProviderModule, acquireSlot, releaseSlot, planPrebuildFor, prebuild, build, ccacheFor, swapApk, readState, now }) {
|
|
807
807
|
const { phase, out, estimates, stats, step, miss, hit: lateHit, place, waitingOn, waitingFor } = progress;
|
|
808
808
|
let fallbackMachine = null;
|
|
809
|
-
let hereReason = "no
|
|
809
|
+
let hereReason = "no remote Mac is paired";
|
|
810
810
|
let slotWaitMs;
|
|
811
811
|
const buildMachine = record.buildMachine ?? "auto";
|
|
812
812
|
const fallBack = (reason, line = reason) => {
|
|
@@ -2584,7 +2584,7 @@ function androidCommand(program) {
|
|
|
2584
2584
|
registerAndroid(program);
|
|
2585
2585
|
}
|
|
2586
2586
|
function registerAndroid(program) {
|
|
2587
|
-
program.command("android").description("Build (or install from the shared cache), install and launch this workspace's Android app on its owned emulator, wired to the reserved Metro port. A Debug run starts the dev server when it is not running.").option("--eas-profile <name>", "Download a matching EAS development build; on a miss, print the build command without running it").option("--slot <name>", "Reusable device slot within this workspace (default: default)", parseDeviceSlotOption).option("--build
|
|
2587
|
+
program.command("android").description("Build (or install from the shared cache), install and launch this workspace's Android app on its owned emulator, wired to the reserved Metro port. A Debug run starts the dev server when it is not running.").option("--eas-profile <name>", "Download a matching EAS development build; on a miss, print the build command without running it").option("--slot <name>", "Reusable device slot within this workspace (default: default)", parseDeviceSlotOption).option("--remote-build <value>", "Build on auto, local, or one named machine; a name refuses without fallback", parseBuildMachineOption).option("--json", "Emit the facts as a single JSON line on stdout; every other line goes to stderr").option("--plan", "Predict the next build without building, booting or installing: resolve the fingerprint, check the local then remote cache, and print the expected cache result and duration. Writes no Stim state.").option("--no-metro-check", "Skip the reserved-port Metro health check and do not start it (the app will load no bundle unless something else serves it)").option("--no-build-cache", "Build fresh, ignoring cached artifacts (local and the project's build-cache provider); the fresh build still replaces the cache entry").option("--variant <name>", "Gradle variant to assemble and install (e.g. productionDebug on a flavored project); overrides the android.variant setting. A variant ending in Release embeds the JS bundle and skips Metro entirely. Default: debug").option("--system-image <id>", "Android system image to create this workspace's owned AVD from, as the sdkmanager package id (e.g. \"system-images;android-36;google_apis;arm64-v8a\"). Overrides the android.systemImage setting for this invocation. An unknown id refuses with STIM_BAD_ARG and prints the installed images.").option("--device-profile <id>", "Hardware profile to create this workspace's owned AVD with, as an `avdmanager list device -c` id (e.g. \"pixel_fold\", \"pixel_tablet\"). Overrides the android.deviceProfile setting for this invocation. An unknown id refuses with STIM_BAD_ARG and prints the available ids.").option("--device [serial]", "Install and launch on a connected physical device instead of this workspace's owned emulator. With no serial, the first connected device this workspace can lease is used. Stim never creates, boots, or deletes a physical device.").option("--remote <target>", "Run on eas, proxy, or a named approved Mac from remote.machines; auto places on an approved Mac when this Mac is full or busy", (value) => {
|
|
2588
2588
|
if (!parseMachine(value)) throw new InvalidArgumentError("expected eas, proxy, auto, or a tailnet machine name");
|
|
2589
2589
|
return value;
|
|
2590
2590
|
}).option("--wait <seconds>", "How long to wait for another workspace to release the device it leases, before refusing with STIM_DEVICE_BUSY (default 60, 0 refuses at once). Without --device, wait for an owned-device slot (default 600 seconds; --no-wait refuses immediately).").option("--no-wait", "Install on a device another workspace leases instead of waiting: this run takes no lease and, when both workspaces build the same app id, the install terminates the holder's running app. Without --device, refuse a full device cap or existing slot queue immediately.").action(async (opts) => {
|
|
@@ -2610,7 +2610,7 @@ function registerAndroid(program) {
|
|
|
2610
2610
|
try {
|
|
2611
2611
|
return await runAndroid({
|
|
2612
2612
|
root,
|
|
2613
|
-
buildMachine: opts.
|
|
2613
|
+
buildMachine: opts.remoteBuild,
|
|
2614
2614
|
slot: opts.slot,
|
|
2615
2615
|
easProfile: opts.easProfile,
|
|
2616
2616
|
json: Boolean(opts.json),
|
|
@@ -16,7 +16,7 @@ import { A as listAvds, I as ownedAvdDirectory, at as isStimOwnedSim, ct as drop
|
|
|
16
16
|
import { _ as parseRuntimeVersion, f as listIosDeviceTypes, u as listAllIosSims } from "./ios-DSfnPfse.mjs";
|
|
17
17
|
import { _ as teardownParkedAvd, d as eraseParkedAvd, f as eraseParkedIosSim, g as teardownOwnedIosSim, m as teardownOwnedAvd, t as resolveSupervisorTarget, v as teardownParkedIosSim } from "./ownership-BMLqyBgJ.mjs";
|
|
18
18
|
import { n as workspaceProcessLockError, t as withWorkspaceProcessLock } from "./workspace-process-lock-2mNzOlaB.mjs";
|
|
19
|
-
import { i as idleShutdownCandidates, n as collectOwnedDeviceActivity, o as shutDownIdleDevices, s as workspaceBuildInProgress, t as collectIdleDevices } from "./idle-
|
|
19
|
+
import { i as idleShutdownCandidates, n as collectOwnedDeviceActivity, o as shutDownIdleDevices, s as workspaceBuildInProgress, t as collectIdleDevices } from "./idle-BXG__1BA.mjs";
|
|
20
20
|
import { a as collectWorkspaceOutputs, r as clearWorkspaceOutputs } from "./workspaces-Bcib97-6.mjs";
|
|
21
21
|
import { n as supervisorError } from "./errors-B6W7FkxQ.mjs";
|
|
22
22
|
import { l as withdrawDevServerStopRequest, s as requestDevServerStop } from "./stop-cause-rhmGfwvt.mjs";
|
|
@@ -490,7 +490,11 @@ function attributeMachineUsage({ processes, footprints, environments, roots, sim
|
|
|
490
490
|
claim(pid, `metro:${env.path}`, workspaceOwner("metro", env, port ? `Metro :${port}` : "Metro", port ? String(port) : null));
|
|
491
491
|
}
|
|
492
492
|
if (root.build && present.has(root.build.pid)) {
|
|
493
|
-
const label =
|
|
493
|
+
const label = {
|
|
494
|
+
ios: "iOS build",
|
|
495
|
+
android: "Android build",
|
|
496
|
+
macos: "macOS build"
|
|
497
|
+
}[root.build.platform];
|
|
494
498
|
claim(root.build.pid, `build:${env.path}`, workspaceOwner("build", env, label, root.build.platform));
|
|
495
499
|
}
|
|
496
500
|
for (const pid of root.macosPids ?? []) if (present.has(pid)) claim(pid, `macos:${env.path}`, workspaceOwner("macos", env, env.macos?.product ?? "macOS app", null));
|
|
@@ -1418,6 +1422,28 @@ async function inspectWatchmanMemory() {
|
|
|
1418
1422
|
}));
|
|
1419
1423
|
}
|
|
1420
1424
|
//#endregion
|
|
1425
|
+
//#region src/commands/gc/archive-selector.ts
|
|
1426
|
+
const KIND_SELECTORS = {
|
|
1427
|
+
"archived-logs": "logs",
|
|
1428
|
+
"archived-recordings": "recordings",
|
|
1429
|
+
"archived-agent": "agentActions"
|
|
1430
|
+
};
|
|
1431
|
+
function parseArchiveSelector(scope) {
|
|
1432
|
+
const trimmed = scope.trim();
|
|
1433
|
+
const colon = trimmed.indexOf(":");
|
|
1434
|
+
const name = (colon === -1 ? trimmed : trimmed.slice(0, colon)).toLowerCase();
|
|
1435
|
+
const id = colon === -1 ? null : trimmed.slice(colon + 1);
|
|
1436
|
+
if (name === "archived") return {
|
|
1437
|
+
kind: null,
|
|
1438
|
+
id
|
|
1439
|
+
};
|
|
1440
|
+
const kind = KIND_SELECTORS[name];
|
|
1441
|
+
return kind ? {
|
|
1442
|
+
kind,
|
|
1443
|
+
id
|
|
1444
|
+
} : null;
|
|
1445
|
+
}
|
|
1446
|
+
//#endregion
|
|
1421
1447
|
//#region src/commands/gc/caches.ts
|
|
1422
1448
|
const DAY_MS$1 = 864e5;
|
|
1423
1449
|
function cacheSweepIsScoped() {
|
|
@@ -1440,12 +1466,7 @@ const WORKSPACE_OUTPUTS = "workspaces";
|
|
|
1440
1466
|
const RECORDINGS = "recordings";
|
|
1441
1467
|
const PARKED_DEVICES = "parked";
|
|
1442
1468
|
function includesArchives(name) {
|
|
1443
|
-
|
|
1444
|
-
return Boolean(wanted && (wanted === "archived" || wanted.startsWith("archived:") || [
|
|
1445
|
-
"archived-logs",
|
|
1446
|
-
"archived-recordings",
|
|
1447
|
-
"archived-agent"
|
|
1448
|
-
].includes(wanted)));
|
|
1469
|
+
return name ? parseArchiveSelector(name) !== null : false;
|
|
1449
1470
|
}
|
|
1450
1471
|
function includesParkedDevices(name) {
|
|
1451
1472
|
return name?.trim().toLowerCase() === PARKED_DEVICES;
|
|
@@ -2713,4 +2734,4 @@ function budgetLine(report) {
|
|
|
2713
2734
|
return `${report.volumes.length ? `${report.volumes.map((v) => `${v.freeGb} GB free on ${v.volume}`).join(", ")} (reclaims below ${Math.max(budget.minFreeDiskGb, budget.hardFloorDiskGb)} GB, ${budget.hardFloorDiskGb ? `refuses below ${budget.hardFloorDiskGb} GB` : "never refuses"})` : "disk budget off"}; ${report.memory ? `roughly ${report.memory.committedGb} GB of a ${budget.maxCommittedMemoryGb} GB memory budget committed` : "memory budget off"}`;
|
|
2714
2735
|
}
|
|
2715
2736
|
//#endregion
|
|
2716
|
-
export { includesWorkspaceOutputs as A,
|
|
2737
|
+
export { sizeCaches as $, includesWorkspaceOutputs as A, collectMemoryReport as B, findStaleProjectDevices as C, includesArchives as D, emptyCaches as E, selectsBeyondCaches as F, memorySweepIsScoped as G, memoryCacheKind as H, trimCaches as I, scopedMemoryReport as J, memoryWorkPending as K, parseArchiveSelector as L, planCacheEmptying as M, previewScopedEmptying as N, includesParkedDevices as O, selectCaches as P, discoverCaches as Q, GRADLE_DAEMONS_KIND as R, findStaleDeviceRecords as S, withAndroidAvdSizes as T, memoryLines as U, inspectWatchmanMemory as V, memoryScope as W, attributeMachineUsage as X, phase as Y, readFootprints as Z, describeParkedSims as _, machineNumber as a, eraseParkedDevices as b, resolveBudget as c, collectDeviceLeases as d, collectParkedAvds as f, deleteProjectDevices as g, deleteParkedSims as h, inspectBudget as i, isWorkspacesScope as j, includesRecordings as k, stopOwnedMetroForReset as l, deleteParkedAvds as m, budgetLine as n, peekBudget as o, collectParkedSims as p, reclaimMemory as q, enforceBudget as r, readVolumeSpace as s, budgetGate as t, DEVICE_LIST_TIMEOUT_MS$1 as u, describeUnverifiableDevices as v, unverifiedDeviceCommand as w, findOrphanedDevices as x, deviceSweepIsScoped as y, WATCHMAN_KIND as z };
|
|
@@ -7,22 +7,22 @@ import { Tt as removeTemporaryEntry, a as androidAvdConfigSetting, at as gitComm
|
|
|
7
7
|
import { u as ownedDeviceLabel } from "./project-D47Rh0ly.mjs";
|
|
8
8
|
import { o as pidExists } from "./metro-g8NqiJp-.mjs";
|
|
9
9
|
import { d as sharedBuildCache } from "./workspace-state-DqcCbpE7.mjs";
|
|
10
|
-
import { o as peekBudget } from "./budget-
|
|
10
|
+
import { o as peekBudget } from "./budget-CUDz870h.mjs";
|
|
11
11
|
import { C as diffFingerprintSources, I as storedSources, w as entryDir, y as artifactIn } from "./device-lease-DpoS36_u.mjs";
|
|
12
12
|
import { A as listAvds, B as ownedAvdSystemImage, E as getAvdNameForSerial, F as ownedAvdDeviceProfile, J as resolveOwnedAvdSerial, L as ownedAvdMatchesConfiguration, O as listAdbDevices, P as nextConsolePort, R as ownedAvdName, W as pickDefaultSystemImage, b as createOwnedAvd, f as assertOwnedAvdStopped, ft as parkedMaxSetting, g as avdPoolConfiguration, j as listInstalledSystemImages, n as OWNED_AVD_CONFIG_DEFAULTS, pt as readParked, st as adoptParked, t as DEFAULT_AVD_DEVICE_PROFILE, tt as waitForBoot, ut as isLegacyDeletionClaim, v as bootAndroidEmulator, y as configureNewOwnedAvd } from "./android-B_YNZy61.mjs";
|
|
13
13
|
import { j as readHostMemoryPressure, u as listAllIosSims } from "./ios-DSfnPfse.mjs";
|
|
14
14
|
import { _ as teardownParkedAvd, m as teardownOwnedAvd } from "./ownership-BMLqyBgJ.mjs";
|
|
15
|
-
import {
|
|
16
|
-
import { b as tailLines, u as HEARTBEAT_INTERVAL_MS, y as startBuildHeartbeat } from "./toolchain-
|
|
15
|
+
import { o as estimateBuild, p as readStats$1 } from "./build-progress-D0WkjCPd.mjs";
|
|
16
|
+
import { b as tailLines, u as HEARTBEAT_INTERVAL_MS, y as startBuildHeartbeat } from "./toolchain-CdrxgUeA.mjs";
|
|
17
17
|
import { t as cleanLine } from "./server-expo-CHTyXD0G.mjs";
|
|
18
|
-
import {
|
|
19
|
-
import { a as call, o as connectHost } from "./hosted-client-
|
|
20
|
-
import { t as clearDeviceIdleShutdown } from "./idle-shutdown-
|
|
21
|
-
import { i as countLiveOwnedDevices, n as DeviceAdmissionRefusal, p as withDeviceBootAdmission, s as peekDeviceSlots } from "./device-capacity-
|
|
18
|
+
import { f as namedBuildMachine, m as resolveBuildMachine, v as hostingMachines } from "./client-CxNotugx.mjs";
|
|
19
|
+
import { a as call, o as connectHost } from "./hosted-client-CdSoH-G6.mjs";
|
|
20
|
+
import { t as clearDeviceIdleShutdown } from "./idle-shutdown-IGyNV8Cr.mjs";
|
|
21
|
+
import { i as countLiveOwnedDevices, n as DeviceAdmissionRefusal, p as withDeviceBootAdmission, s as peekDeviceSlots } from "./device-capacity-ZC4XSZ4R.mjs";
|
|
22
22
|
import { i as staleNativeDirRefusal } from "./prebuild-D7RUMkwN.mjs";
|
|
23
|
-
import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-
|
|
23
|
+
import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-C2Um-XUR.mjs";
|
|
24
24
|
import { r as readHostedNative, s as writeHostedNative } from "./ios-state-8L3lgum6.mjs";
|
|
25
|
-
import { n as prepareHostedNative } from "./hosted-native-
|
|
25
|
+
import { n as prepareHostedNative } from "./hosted-native-CZLOrMrN.mjs";
|
|
26
26
|
import { a as easAuthNote } from "./remote-cache-Ci4DQYYj.mjs";
|
|
27
27
|
import { t as reconcileSimSlim } from "./simslim-BWNrc3M3.mjs";
|
|
28
28
|
import { randomUUID } from "node:crypto";
|
|
@@ -69,7 +69,7 @@ function decideDevicePlacement(inputs) {
|
|
|
69
69
|
const cannotTake = !(max === 0 || count !== null && count < max) || queued > 0;
|
|
70
70
|
const usage = max > 0 ? `${count} of ${max} devices in use` : `${count} devices in use, no device cap`;
|
|
71
71
|
const localReason = count === null ? "cannot tell how many devices run here; local boot admission decides" : cannotTake ? `${usage}${queued ? `, ${queued} runs queued ahead` : ""}` : here.budgetRefusal ?? (here.memoryPressure !== "normal" ? `host memory pressure ${here.memoryPressure ?? "unknown"} here` : `load ${here.loadPerCore.toFixed(1)}/core here, ${usage}`);
|
|
72
|
-
if (!offers.length) return local$1("no
|
|
72
|
+
if (!offers.length) return local$1("no remote Macs configured; " + localReason);
|
|
73
73
|
if (count === null) return local$1(localReason);
|
|
74
74
|
if (!cannotTake && here.memoryPressure === "normal" && !here.budgetRefusal && here.loadPerCore < here.maxLoadPerCore) return local$1(localReason);
|
|
75
75
|
const skipped = [];
|
|
@@ -99,7 +99,7 @@ function decideDevicePlacement(inputs) {
|
|
|
99
99
|
if (!admitted.length) return local$1(`${localReason}; no host admits${cannotTake && !noWait ? "; waiting locally if needed" : ""}`, skipped);
|
|
100
100
|
const machines = admitted.map(({ machine, offer }) => ({
|
|
101
101
|
machine,
|
|
102
|
-
reason: `${localReason}; ${machine}${machine === buildMachine ? " is the explicit
|
|
102
|
+
reason: `${localReason}; ${machine}${machine === buildMachine ? " is the explicit remote Mac," : ""} load ${offer.resources.loadPerCore === null ? "unknown" : offer.resources.loadPerCore.toFixed(1) + "/core"}`
|
|
103
103
|
}));
|
|
104
104
|
return {
|
|
105
105
|
kind: "host",
|
|
@@ -185,7 +185,7 @@ function local(reason, skipped = []) {
|
|
|
185
185
|
skipped
|
|
186
186
|
};
|
|
187
187
|
}
|
|
188
|
-
async function automaticDevicePlacement({ root, slot, platform, selectors, buildMachine, noWait }, { machines =
|
|
188
|
+
async function automaticDevicePlacement({ root, slot, platform, selectors, buildMachine, noWait }, { machines = hostingMachines, read = readHostedNative, write = writeHostedNative, resume = prepareHostedNative, peek = () => peekDeviceSlots({
|
|
189
189
|
platform,
|
|
190
190
|
project: getProject(root),
|
|
191
191
|
slot
|
|
@@ -211,8 +211,8 @@ async function automaticDevicePlacement({ root, slot, platform, selectors, build
|
|
|
211
211
|
sticky: true
|
|
212
212
|
};
|
|
213
213
|
const entries = machines();
|
|
214
|
-
if (entries === null) throw Object.assign(/* @__PURE__ */ new Error("
|
|
215
|
-
const preference = resolveBuildMachine(buildMachine, process.env.
|
|
214
|
+
if (entries === null) throw Object.assign(/* @__PURE__ */ new Error("remote.machines is invalid. Run stim guide settings and correct it."), { code: "STIM_HOSTING_REFUSED" });
|
|
215
|
+
const preference = resolveBuildMachine(buildMachine, process.env.STIM_REMOTE_BUILD, loadConfig$1()?.remote?.build);
|
|
216
216
|
buildMachine = namedBuildMachine(preference) ? preference : void 0;
|
|
217
217
|
const load = capacity();
|
|
218
218
|
const here = {
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import { D as withConfigLock$1
|
|
1
|
+
import { D as withConfigLock$1 } from "./config-D0DbpZtM.mjs";
|
|
2
2
|
import { n as ownership_claim_exports } from "./process-identity-BmRm1qV0.mjs";
|
|
3
|
-
import { a as formatElapsed,
|
|
4
|
-
import { a as updateWorkspaceState,
|
|
5
|
-
import { i as recordGcResult } from "./in-use-CvGOUn-x.mjs";
|
|
6
|
-
import { o as idleForMs, r as createActivityReader } from "./activity-IRvJY_ru.mjs";
|
|
7
|
-
import { z as ownedAvdSerialResolver } from "./android-B_YNZy61.mjs";
|
|
8
|
-
import { g as teardownOwnedIosSim, m as teardownOwnedAvd } from "./ownership-BMLqyBgJ.mjs";
|
|
3
|
+
import { a as formatElapsed, u as plural } from "./command-output-CDAIFD-8.mjs";
|
|
4
|
+
import { a as updateWorkspaceState, t as clearWorkspaceStateKey } from "./workspace-state-DqcCbpE7.mjs";
|
|
9
5
|
import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
10
6
|
import { dirname } from "node:path";
|
|
11
7
|
import { BUILD_HISTORY_KEY, BUILD_HISTORY_LIMIT, BUILD_PHASES, LAST_BUILD_KEYS, STATS_VERSION, decodeStats, isJsonObject, parseMissReason, readRunEstimates, readStats as readStats$1, statsFile, statsProjectKey as statsProjectKey$1, trimCapacityRefusals, trimCapacityWaits, trimSamples, wholePhases, workspaceBuildDetailFile } from "@stim-cli/core/state";
|
|
12
|
-
import chalk from "chalk";
|
|
13
8
|
//#region src/engine/stats.ts
|
|
14
9
|
const PLACEMENT_MAX_AGE_MS = 6048e5;
|
|
15
10
|
function emptyStats() {
|
|
@@ -351,6 +346,13 @@ const GRADLE_TASK = /^> Task (:\S+)/;
|
|
|
351
346
|
*/
|
|
352
347
|
const XCODE_TARGET_DONE = /^(Touch|RegisterExecutionPolicyException|CodeSign)$/;
|
|
353
348
|
const GRADLE_CONFIGURE = /^> Configure project /;
|
|
349
|
+
/**
|
|
350
|
+
* SwiftPM prints `[done / total] name` once it plans the build (with U+2009 thin spaces around the slash in Swift 6.4
|
|
351
|
+
* output), `[done/total] Compiling ...` in older toolchains; Swift 6.4 names the target being worked on, and
|
|
352
|
+
* `<product>-product` is the link of a product.
|
|
353
|
+
*/
|
|
354
|
+
const SWIFTPM_PROGRESS = /^\[(\d+)\s*\/\s*(\d+)\](?:\s+(.*))?$/;
|
|
355
|
+
const SWIFTPM_CONFIGURE = /^(Fetching|Fetched|Computing version|Computed|Creating working copy|Working copy of)\b|^\[(Pre-planning|Planning|Using on-disk description)/;
|
|
354
356
|
const XCODE_STEPS = [
|
|
355
357
|
[/^(CpResource|CopyPNGFile|CopyStringsFile|CompileAssetCatalog\w*|CompileStoryboard|CompileXIB|LinkStoryboards|ProcessInfoPlistFile)$/, "resources"],
|
|
356
358
|
[/^(Compile\w*|Swift\w*|ScanDependencies|Precompile\w*)$/, "compile"],
|
|
@@ -388,8 +390,23 @@ function shortXcodeAction(action, args, target) {
|
|
|
388
390
|
const subject = action === "PhaseScriptExecution" ? unescape(tokens[0] ?? "") : baseName(unescape(tokens.findLast((token) => token.startsWith("/")) ?? ""));
|
|
389
391
|
return clip(`${action}${subject ? ` ${subject}` : ""} (${target})`);
|
|
390
392
|
}
|
|
391
|
-
|
|
393
|
+
function swiftpmStep(text) {
|
|
394
|
+
return /^Linking\b|-product$/.test(text) ? "link" : "compile";
|
|
395
|
+
}
|
|
396
|
+
/** What one line of xcodebuild, Gradle or SwiftPM output says about the build's progress, or null for any other line. */
|
|
392
397
|
function parseBuildToolLine(msg) {
|
|
398
|
+
const counted = SWIFTPM_PROGRESS.exec(msg);
|
|
399
|
+
if (counted) {
|
|
400
|
+
const text = counted[3]?.trim() ?? "";
|
|
401
|
+
return {
|
|
402
|
+
kind: "count",
|
|
403
|
+
done: Number(counted[1]),
|
|
404
|
+
total: Number(counted[2]),
|
|
405
|
+
step: swiftpmStep(text),
|
|
406
|
+
line: text ? clip(text) : null
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
if (SWIFTPM_CONFIGURE.test(msg)) return { kind: "configure" };
|
|
393
410
|
const graph = TARGET_GRAPH.exec(msg);
|
|
394
411
|
if (graph) return {
|
|
395
412
|
kind: "total",
|
|
@@ -426,7 +443,8 @@ function parseBuildToolLine(msg) {
|
|
|
426
443
|
}
|
|
427
444
|
/**
|
|
428
445
|
* Accumulates a build's tool output into its detail: xcodebuild counts the distinct targets it finished against the
|
|
429
|
-
* total its dependency graph note gives; Gradle counts the task lines it printed and has no total
|
|
446
|
+
* total its dependency graph note gives; Gradle counts the task lines it printed and has no total; SwiftPM reports
|
|
447
|
+
* its own `[done / total]` counts, which the parser passes through.
|
|
430
448
|
*/
|
|
431
449
|
function createBuildDetailParser() {
|
|
432
450
|
let seen = false;
|
|
@@ -435,6 +453,7 @@ function createBuildDetailParser() {
|
|
|
435
453
|
let total = null;
|
|
436
454
|
let line = null;
|
|
437
455
|
let tasks = 0;
|
|
456
|
+
let counted = null;
|
|
438
457
|
const targets = /* @__PURE__ */ new Set();
|
|
439
458
|
return {
|
|
440
459
|
push(msg) {
|
|
@@ -450,6 +469,16 @@ function createBuildDetailParser() {
|
|
|
450
469
|
step = "configure";
|
|
451
470
|
return true;
|
|
452
471
|
}
|
|
472
|
+
if (parsed.kind === "count") {
|
|
473
|
+
unit = "steps";
|
|
474
|
+
counted = {
|
|
475
|
+
done: parsed.done,
|
|
476
|
+
total: parsed.total
|
|
477
|
+
};
|
|
478
|
+
step = parsed.step;
|
|
479
|
+
if (parsed.line) line = parsed.line;
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
453
482
|
unit = parsed.unit;
|
|
454
483
|
if (parsed.unit === "tasks") tasks += 1;
|
|
455
484
|
else if (parsed.finished) targets.add(parsed.id);
|
|
@@ -459,6 +488,14 @@ function createBuildDetailParser() {
|
|
|
459
488
|
},
|
|
460
489
|
detail(updatedAt) {
|
|
461
490
|
if (!seen) return null;
|
|
491
|
+
if (unit === "steps" && counted) return {
|
|
492
|
+
step,
|
|
493
|
+
unit,
|
|
494
|
+
done: Math.min(counted.done, counted.total),
|
|
495
|
+
total: counted.total,
|
|
496
|
+
line,
|
|
497
|
+
updatedAt
|
|
498
|
+
};
|
|
462
499
|
const done = unit === "tasks" ? tasks : unit === "targets" ? targets.size : null;
|
|
463
500
|
return {
|
|
464
501
|
step,
|
|
@@ -591,7 +628,7 @@ function startBuildProgress({ root, platform, slot, claim, now = Date.now, note
|
|
|
591
628
|
};
|
|
592
629
|
const settle = (outcome) => {
|
|
593
630
|
record.outcome = outcome;
|
|
594
|
-
if (projectKey) record.estimate = estimateBuild(projectHistory(projectKey), platform, outcome, record.deviceSetup);
|
|
631
|
+
if (projectKey && platform !== "macos") record.estimate = estimateBuild(projectHistory(projectKey), platform, outcome, record.deviceSetup);
|
|
595
632
|
};
|
|
596
633
|
const waits = /* @__PURE__ */ new Map();
|
|
597
634
|
return {
|
|
@@ -605,11 +642,12 @@ function startBuildProgress({ root, platform, slot, claim, now = Date.now, note
|
|
|
605
642
|
startedAt: at
|
|
606
643
|
});
|
|
607
644
|
if (phase !== "wait") delete record.waitingOn;
|
|
608
|
-
const outcome = record.outcome ? null : settledOutcome(phase, record.phases);
|
|
645
|
+
const outcome = record.outcome || platform === "macos" ? null : settledOutcome(phase, record.phases);
|
|
609
646
|
if (outcome) settle(outcome);
|
|
610
647
|
write();
|
|
611
648
|
},
|
|
612
649
|
estimate(key) {
|
|
650
|
+
if (platform === "macos") return;
|
|
613
651
|
projectKey = key;
|
|
614
652
|
record.estimate = estimateBuild(projectHistory(key), platform, record.outcome ?? null, record.outcome ? record.deviceSetup : void 0);
|
|
615
653
|
write();
|
|
@@ -758,7 +796,7 @@ function recordFinishedBuild(root, record, { update = updateWorkspaceState, now
|
|
|
758
796
|
const slots = isJsonObject(state.deviceSlots) ? state.deviceSlots : {};
|
|
759
797
|
const savedSlot = isJsonObject(slots[slot]) ? slots[slot] : {};
|
|
760
798
|
const savedDevice = slot === "default" ? state[platform] : savedSlot[platform];
|
|
761
|
-
if (record.devicePlacement || isJsonObject(savedDevice)) {
|
|
799
|
+
if (platform !== "macos" && (record.devicePlacement || isJsonObject(savedDevice))) {
|
|
762
800
|
const device = isJsonObject(savedDevice) ? { ...savedDevice } : {};
|
|
763
801
|
if (record.devicePlacement) device.devicePlacement = record.devicePlacement;
|
|
764
802
|
else delete device.devicePlacement;
|
|
@@ -776,6 +814,7 @@ function recordFinishedBuild(root, record, { update = updateWorkspaceState, now
|
|
|
776
814
|
}
|
|
777
815
|
};
|
|
778
816
|
}
|
|
817
|
+
if (platform === "macos") return withHistoryEntry(state, platform, entry);
|
|
779
818
|
return withHistoryEntry({
|
|
780
819
|
...state,
|
|
781
820
|
lastBuild: record,
|
|
@@ -786,7 +825,7 @@ function recordFinishedBuild(root, record, { update = updateWorkspaceState, now
|
|
|
786
825
|
function withInterruptedBuild(state) {
|
|
787
826
|
const left = parseActiveBuild(state[ACTIVE_BUILD_KEY]);
|
|
788
827
|
if (!left) return state;
|
|
789
|
-
const last = state[LAST_BUILD_KEYS[left.platform]];
|
|
828
|
+
const last = left.platform === "macos" ? state[BUILD_HISTORY_KEY]?.macos?.[0] : state[LAST_BUILD_KEYS[left.platform]];
|
|
790
829
|
if (Date.parse(String(last?.startedAt)) >= Date.parse(left.startedAt)) return state;
|
|
791
830
|
return withHistoryEntry(state, left.platform, {
|
|
792
831
|
platform: left.platform,
|
|
@@ -810,7 +849,7 @@ function parseActiveBuild(value) {
|
|
|
810
849
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
811
850
|
const record = value;
|
|
812
851
|
const claim = record.claim;
|
|
813
|
-
if (record.platform !== "ios" && record.platform !== "android") return null;
|
|
852
|
+
if (record.platform !== "ios" && record.platform !== "android" && record.platform !== "macos") return null;
|
|
814
853
|
if (!isPhase(record.phase)) return null;
|
|
815
854
|
if (typeof record.startedAt !== "string" || typeof record.phaseStartedAt !== "string") return null;
|
|
816
855
|
if (!claim || typeof claim.root !== "string" || typeof claim.claimId !== "string") return null;
|
|
@@ -906,7 +945,7 @@ function median(values) {
|
|
|
906
945
|
return sorted.length % 2 ? sorted[mid] : Math.round((sorted[mid - 1] + sorted[mid]) / 2);
|
|
907
946
|
}
|
|
908
947
|
function estimateBuild(history, platform, known, deviceSetup) {
|
|
909
|
-
const lists = history?.[platform];
|
|
948
|
+
const lists = platform === "macos" ? void 0 : history?.[platform];
|
|
910
949
|
const outcome = known ?? latestOutcome(lists);
|
|
911
950
|
const samples = matchDeviceSetup(outcome && lists?.[outcome] || [], deviceSetup);
|
|
912
951
|
const phaseMs = {};
|
|
@@ -994,170 +1033,4 @@ function buildStatusLine(report, now) {
|
|
|
994
1033
|
return remainingMs > 0 ? `${head} -- ${remainingText(remainingMs)} (${basis})` : `${head} (usually ~${formatElapsed(report.expectedMs)}, ${basis})`;
|
|
995
1034
|
}
|
|
996
1035
|
//#endregion
|
|
997
|
-
|
|
998
|
-
function findOwnedDeviceActivity({ config, sims, androidSerial, readActivity, deadProjects = [] }) {
|
|
999
|
-
const booted = new Map(sims.filter((sim) => sim.state === "Booted").map((sim) => [sim.udid, sim.name]));
|
|
1000
|
-
const dead = new Set(deadProjects);
|
|
1001
|
-
const found = [];
|
|
1002
|
-
for (const [project, record] of Object.entries(config?.projects ?? {})) {
|
|
1003
|
-
if (dead.has(project)) continue;
|
|
1004
|
-
for (const { slot, platforms } of projectDeviceSlots(record)) {
|
|
1005
|
-
const ios = platforms.ios;
|
|
1006
|
-
if (ios?.owned && ios.deviceUdid && booted.has(ios.deviceUdid)) found.push({
|
|
1007
|
-
kind: "ios",
|
|
1008
|
-
id: ios.deviceUdid,
|
|
1009
|
-
name: booted.get(ios.deviceUdid) ?? ios.deviceUdid,
|
|
1010
|
-
project,
|
|
1011
|
-
slot,
|
|
1012
|
-
activity: readActivity({
|
|
1013
|
-
platform: "ios",
|
|
1014
|
-
id: ios.deviceUdid,
|
|
1015
|
-
slot,
|
|
1016
|
-
workspace: project
|
|
1017
|
-
})
|
|
1018
|
-
});
|
|
1019
|
-
const android = platforms.android;
|
|
1020
|
-
const serial = android?.owned && android.avdName ? androidSerial(android.avdName) : null;
|
|
1021
|
-
if (android?.avdName && serial) found.push({
|
|
1022
|
-
kind: "android",
|
|
1023
|
-
id: android.avdName,
|
|
1024
|
-
name: android.avdName,
|
|
1025
|
-
project,
|
|
1026
|
-
slot,
|
|
1027
|
-
activity: readActivity({
|
|
1028
|
-
platform: "android",
|
|
1029
|
-
id: serial,
|
|
1030
|
-
slot,
|
|
1031
|
-
workspace: project
|
|
1032
|
-
})
|
|
1033
|
-
});
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
return found;
|
|
1037
|
-
}
|
|
1038
|
-
function findIdleDevices({ buildInProgress, now, ...inputs }) {
|
|
1039
|
-
return findOwnedDeviceActivity(inputs).filter((device) => device.activity.state === "idle").map(({ kind, id, name, project, slot, activity }) => ({
|
|
1040
|
-
kind,
|
|
1041
|
-
id,
|
|
1042
|
-
name,
|
|
1043
|
-
project,
|
|
1044
|
-
slot,
|
|
1045
|
-
lastActivityAt: activity.lastActivityAt ?? null,
|
|
1046
|
-
idleForMs: idleForMs(activity, now),
|
|
1047
|
-
buildInProgress: buildInProgress(project)
|
|
1048
|
-
}));
|
|
1049
|
-
}
|
|
1050
|
-
function idleShutdownCandidates(devices, idleMs) {
|
|
1051
|
-
return devices.filter((d) => !d.buildInProgress && d.idleForMs !== null && d.idleForMs >= idleMs);
|
|
1052
|
-
}
|
|
1053
|
-
function parseIdleDuration(value) {
|
|
1054
|
-
const match = /^([1-9][0-9]*)(m|h|d)$/.exec(value.trim());
|
|
1055
|
-
if (!match) return null;
|
|
1056
|
-
const unit = {
|
|
1057
|
-
m: 6e4,
|
|
1058
|
-
h: 36e5,
|
|
1059
|
-
d: 864e5
|
|
1060
|
-
}[match[2]];
|
|
1061
|
-
return Number(match[1]) * unit;
|
|
1062
|
-
}
|
|
1063
|
-
function workspaceBuildInProgress(project) {
|
|
1064
|
-
const record = parseActiveBuild(readWorkspaceState$1(project)?.[ACTIVE_BUILD_KEY]);
|
|
1065
|
-
if (!record) return false;
|
|
1066
|
-
try {
|
|
1067
|
-
return activeBuildState(record.claim) !== "stale";
|
|
1068
|
-
} catch {
|
|
1069
|
-
return true;
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
function deviceActivityInputs(config, sims, now) {
|
|
1073
|
-
const resolve = ownedAvdSerialResolver({ timeoutMs: 5e3 });
|
|
1074
|
-
return {
|
|
1075
|
-
config,
|
|
1076
|
-
sims,
|
|
1077
|
-
readActivity: createActivityReader({ now }),
|
|
1078
|
-
androidSerial: (avdName) => {
|
|
1079
|
-
try {
|
|
1080
|
-
return resolve(avdName).serial ?? null;
|
|
1081
|
-
} catch {
|
|
1082
|
-
return null;
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
};
|
|
1086
|
-
}
|
|
1087
|
-
function collectOwnedDeviceActivity(config, sims, now = Date.now()) {
|
|
1088
|
-
return findOwnedDeviceActivity(deviceActivityInputs(config, sims, now));
|
|
1089
|
-
}
|
|
1090
|
-
function collectIdleDevices(config, sims, deadProjects, now = Date.now()) {
|
|
1091
|
-
return findIdleDevices({
|
|
1092
|
-
...deviceActivityInputs(config, sims, now),
|
|
1093
|
-
deadProjects,
|
|
1094
|
-
now,
|
|
1095
|
-
buildInProgress: workspaceBuildInProgress
|
|
1096
|
-
});
|
|
1097
|
-
}
|
|
1098
|
-
function idleDeviceLines(devices) {
|
|
1099
|
-
if (devices.length === 0) return [];
|
|
1100
|
-
return [`Idle owned devices (${devices.length}) - booted with no driver, claim, or recent activity:`, ...devices.map((d) => {
|
|
1101
|
-
const slot = d.slot === "default" ? "" : ` [${d.slot}]`;
|
|
1102
|
-
const idle = d.idleForMs === null ? "idle for an unknown time" : `idle ${formatLongDuration(d.idleForMs)}`;
|
|
1103
|
-
const build = d.buildInProgress ? ", build in progress" : "";
|
|
1104
|
-
return ` ${d.kind}${slot} ${d.name} (${d.project}) -- ${idle}${build}`;
|
|
1105
|
-
})];
|
|
1106
|
-
}
|
|
1107
|
-
function shutDownIdleDevices(devices, idleMs, recollect) {
|
|
1108
|
-
const candidates = idleShutdownCandidates(devices, idleMs);
|
|
1109
|
-
const shutDown = [];
|
|
1110
|
-
if (candidates.length === 0) {
|
|
1111
|
-
console.log(chalk.dim(`No owned device has been idle for ${formatLongDuration(idleMs)} or more.`));
|
|
1112
|
-
return {
|
|
1113
|
-
failures: 0,
|
|
1114
|
-
shutDown
|
|
1115
|
-
};
|
|
1116
|
-
}
|
|
1117
|
-
const fresh = idleShutdownCandidates(recollect(), idleMs);
|
|
1118
|
-
let failures = 0;
|
|
1119
|
-
for (const device of candidates) {
|
|
1120
|
-
const what = `${device.kind} ${device.name}`;
|
|
1121
|
-
const current = fresh.find((d) => d.kind === device.kind && d.id === device.id && d.project === device.project && d.slot === device.slot);
|
|
1122
|
-
if (!current) {
|
|
1123
|
-
console.log(chalk.dim(`Kept ${what}: it is no longer idle for ${formatLongDuration(idleMs)}.`));
|
|
1124
|
-
recordGcResult("idleDevice", "kept", device.name, {
|
|
1125
|
-
id: device.id,
|
|
1126
|
-
detail: `it is no longer idle for ${formatLongDuration(idleMs)}`
|
|
1127
|
-
});
|
|
1128
|
-
continue;
|
|
1129
|
-
}
|
|
1130
|
-
const outcome = device.kind === "ios" ? teardownOwnedIosSim(device.id, { label: device.name }) : teardownOwnedAvd(device.id, { owner: {
|
|
1131
|
-
projectPath: device.project,
|
|
1132
|
-
slot: device.slot
|
|
1133
|
-
} });
|
|
1134
|
-
if (outcome.status === "torn-down") {
|
|
1135
|
-
shutDown.push(device);
|
|
1136
|
-
console.log(chalk.green(`Shut down ${what}, idle ${formatLongDuration(current.idleForMs)}`));
|
|
1137
|
-
recordGcResult("idleDevice", "done", device.name, {
|
|
1138
|
-
id: device.id,
|
|
1139
|
-
detail: `idle ${formatLongDuration(current.idleForMs)}`
|
|
1140
|
-
});
|
|
1141
|
-
} else if (outcome.status === "missing") console.log(chalk.dim(`${what} is already gone; nothing to shut down.`));
|
|
1142
|
-
else if (outcome.status === "skipped") {
|
|
1143
|
-
console.log(chalk.yellow(`Skipped ${what}: ${outcome.reason}`));
|
|
1144
|
-
recordGcResult("idleDevice", "kept", device.name, {
|
|
1145
|
-
id: device.id,
|
|
1146
|
-
detail: outcome.reason
|
|
1147
|
-
});
|
|
1148
|
-
} else {
|
|
1149
|
-
failures++;
|
|
1150
|
-
console.log(chalk.red(`Failed to shut down ${what}: ${outcome.reason}`));
|
|
1151
|
-
recordGcResult("idleDevice", "failed", device.name, {
|
|
1152
|
-
id: device.id,
|
|
1153
|
-
detail: outcome.reason
|
|
1154
|
-
});
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
return {
|
|
1158
|
-
failures,
|
|
1159
|
-
shutDown
|
|
1160
|
-
};
|
|
1161
|
-
}
|
|
1162
|
-
//#endregion
|
|
1163
|
-
export { recordRunStats as C, recordCapacityWait as S, tapBuildLog as _, parseIdleDuration as a, readStats$1 as b, ACTIVE_BUILD_KEY as c, buildReport as d, buildStatusLine as f, startBuildProgress as g, recordFinishedBuild as h, idleShutdownCandidates as i, NO_BUILD_PROGRESS as l, parseActiveBuild as m, collectOwnedDeviceActivity as n, shutDownIdleDevices as o, estimateBuild as p, idleDeviceLines as r, workspaceBuildInProgress as s, collectIdleDevices as t, activeBuildState as u, createRunRecorder as v, statsProjectKey$1 as w, recordCapacityRefusal as x, readRunEstimates as y };
|
|
1036
|
+
export { statsProjectKey$1 as _, buildStatusLine as a, recordFinishedBuild as c, createRunRecorder as d, readRunEstimates as f, recordRunStats as g, recordCapacityWait as h, buildReport as i, startBuildProgress as l, recordCapacityRefusal as m, NO_BUILD_PROGRESS as n, estimateBuild as o, readStats$1 as p, activeBuildState as r, parseActiveBuild as s, ACTIVE_BUILD_KEY as t, tapBuildLog as u };
|
|
@@ -3,23 +3,23 @@ import { readFileSync } from "node:fs";
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
//#region bin/cli.ts
|
|
5
5
|
const commands = /* @__PURE__ */ new Map([
|
|
6
|
-
["doctor", () => import("./doctor-
|
|
7
|
-
["worktree", () => import("./worktree-
|
|
8
|
-
["start", () => import("./start-
|
|
6
|
+
["doctor", () => import("./doctor-BF_435OC.mjs")],
|
|
7
|
+
["worktree", () => import("./worktree-CsAjSmEo.mjs")],
|
|
8
|
+
["start", () => import("./start-BEP-XmEA.mjs")],
|
|
9
9
|
["ports", () => import("./ports-4nYqxPWC.mjs")],
|
|
10
|
-
["stop", () => import("./stop-
|
|
11
|
-
["ios", () => import("./ios-
|
|
12
|
-
["android", () => import("./android
|
|
13
|
-
["web", () => import("./web-
|
|
14
|
-
["macos", () => import("./macos-
|
|
15
|
-
["reload", () => import("./reload-
|
|
10
|
+
["stop", () => import("./stop-DOxwkH4j.mjs")],
|
|
11
|
+
["ios", () => import("./ios-C7JuT1bI.mjs")],
|
|
12
|
+
["android", () => import("./android-B6rDWrTm.mjs")],
|
|
13
|
+
["web", () => import("./web-DddUdJzr.mjs")],
|
|
14
|
+
["macos", () => import("./macos-BEs8cwKx.mjs")],
|
|
15
|
+
["reload", () => import("./reload-byOjE3P4.mjs")],
|
|
16
16
|
["device", () => import("./device-C8IOoJPv.mjs")],
|
|
17
|
-
["logs", () => import("./logs-
|
|
17
|
+
["logs", () => import("./logs-DNxKcok9.mjs")],
|
|
18
18
|
["settings", () => import("./settings-SR9OmW9h.mjs")],
|
|
19
|
-
["status", () => import("./status-
|
|
19
|
+
["status", () => import("./status-CqeWbIWW.mjs")],
|
|
20
20
|
["stats", () => import("./stats-Bq4fJOdB.mjs")],
|
|
21
|
-
["gc", () => import("./gc-
|
|
22
|
-
["guide", () => import("./guide-
|
|
21
|
+
["gc", () => import("./gc-BsWKa_-d.mjs")],
|
|
22
|
+
["guide", () => import("./guide-DC3n6-NH.mjs")]
|
|
23
23
|
]);
|
|
24
24
|
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
25
25
|
const program = new Command();
|
package/dist/cli.mjs
CHANGED
|
@@ -4,6 +4,6 @@ const encode = (version) => version.split(".", 3).reduce((sum, part) => sum * 1e
|
|
|
4
4
|
if (encode(process.versions.node) < encode("22.12.0")) {
|
|
5
5
|
process.stderr.write(`STIM_NODE_UNSUPPORTED: Stim needs Node 22.12.0 or later; this is Node ${process.versions.node} at ${process.execPath}. To run Stim where a project pins an older Node, see https://stim.appandflow.com/docs/requirements#older-node-pins\n`);
|
|
6
6
|
process.exitCode = 1;
|
|
7
|
-
} else import("./cli-
|
|
7
|
+
} else import("./cli-BLQqDGlX.mjs");
|
|
8
8
|
//#endregion
|
|
9
9
|
export {};
|