stim 1.8.0 → 1.9.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 +23 -155
- package/dist/{android-BRgBYzU0.mjs → android-BPGizezh.mjs} +112 -135
- package/dist/{android-DeYdjjBP.mjs → android-DEgo4oCo.mjs} +2 -2
- package/dist/{android-DWssqHQ8.mjs → android-_y4Ohi5z.mjs} +54 -15
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{android-cas-SWIjzeuL.mjs → android-cas-eiExNLf7.mjs} +21 -14
- package/dist/app-install-Uf3a83Tv.mjs +819 -0
- package/dist/{build-lock-CgtsB6TV.mjs → build-lock-DPXPLgTc.mjs} +120 -24
- package/dist/build-progress-CVqkfPC6.mjs +188 -0
- package/dist/{cache-manifest-CYJi8-Hx.mjs → cache-manifest-Dg7OnMrp.mjs} +4 -4
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +22 -19
- package/dist/collector-run.d.mts +2 -0
- package/dist/collector-run.mjs +10 -9
- package/dist/{command-output-B3ycpsYv.mjs → command-output-gByVmIjy.mjs} +11 -2
- package/dist/{config-B7iyKWkL.mjs → config-Cp9lM3wX.mjs} +187 -57
- package/dist/{dependency-state-D0M7oKA7.mjs → dependency-state-Bq5DcLGn.mjs} +2 -2
- package/dist/{deps-oCXVNEqQ.mjs → deps-Cip5vUm1.mjs} +8 -5
- package/dist/{detached-entry-Bpo6ZY_I.mjs → detached-entry-KEu0_AXL.mjs} +1 -1
- package/dist/{device-BUoZyMoR.mjs → dev-client-HyqISM0h.mjs} +1178 -635
- package/dist/{device-RdujjHLB.mjs → device-D4U-xLty.mjs} +13 -20
- package/dist/{device-lease-Ffz_M5t0.mjs → device-lease-Crs-HkJY.mjs} +16 -9
- package/dist/{device-pool-BxRwdufO.mjs → device-pool-CnTAz8X1.mjs} +7 -7
- package/dist/{device-remote-ByN8P6CB.mjs → device-remote-AQ5rQPqr.mjs} +482 -35
- package/dist/{doctor-BMt156qe.mjs → doctor-B_Ei3bZu.mjs} +95 -107
- package/dist/{error-diagnostics-D1Kaf-eT.mjs → error-diagnostics-Vfz83GCF.mjs} +22 -16
- package/dist/exec-jIAlgilk.mjs +132 -0
- package/dist/{gc-v2YcoJvm.mjs → gc-Ckw8RQHi.mjs} +763 -126
- package/dist/{guide-BTAlD1_y.mjs → guide-BiAbhs1J.mjs} +891 -501
- package/dist/{guide-status-Craq9z0t.mjs → guide-status-BAMVU0ZA.mjs} +5 -3
- package/dist/{ios-BcCiI4TS.mjs → ios-BL2NFckr.mjs} +43 -20
- package/dist/{ios-BP04pY5f.mjs → ios-BzUJWk1K.mjs} +141 -175
- package/dist/{ios-device-CauFJiYx.mjs → ios-device-D972i9wf.mjs} +149 -52
- package/dist/{ios-device-CFXA46ez.mjs → ios-device-DPsSm0v_.mjs} +3 -2
- package/dist/launch-verify-Q_OtW1Rf.mjs +365 -0
- package/dist/{logs-CakdBTtm.mjs → logs-CI9NQSK7.mjs} +18 -13
- package/dist/{logs-query-BGL-Pl12.mjs → logs-query-Cqma3WIu.mjs} +36 -28
- package/dist/{metro-C7bcJ0uo.mjs → metro-DrLHaMn2.mjs} +78 -8
- package/dist/{named-ports-DzMOlmaX.mjs → named-ports-CmLQSIRj.mjs} +4 -4
- package/dist/{ndjson-BZwI1NBv.mjs → ndjson-9uFNRwfe.mjs} +36 -3
- package/dist/{ownership-Cp52QAK1.mjs → ownership-D15Op8vN.mjs} +3 -3
- package/dist/{ownership-wolE-0Do.mjs → ownership-DCQPuWEc.mjs} +26 -7
- package/dist/{ports-BIbJaKNW.mjs → ports-BNKoWVWZ.mjs} +3 -3
- package/dist/{process-output-Dl5uKE03.mjs → process-output-Fpl8PYi8.mjs} +1 -1
- package/dist/{project-DDZWf_16.mjs → project-DS112DYB.mjs} +8 -3
- package/dist/{reload-BdypPbjM.mjs → reload-ZNJUo1pl.mjs} +12 -13
- package/dist/{server-bare-BQkyxa_b.mjs → server-bare-DWkkcIxV.mjs} +2 -2
- package/dist/{server-expo-BVAA1OqJ.mjs → server-expo-B_lctBR3.mjs} +8 -7
- package/dist/server-expo-CeILEu86.mjs +2 -0
- package/dist/settings-BKNh5rl4.mjs +376 -0
- package/dist/{settings-BXXorVM2.mjs → settings-D030k0t4.mjs} +464 -152
- package/dist/settings.schema.json +989 -0
- package/dist/{teardown-BJqEzPo_.mjs → sim-pool-KaIsp2Ft.mjs} +14 -419
- package/dist/simslim-B_LsGLuJ.mjs +259 -0
- package/dist/{slot-launch-ZUUe0TQP.mjs → slot-launch-DU9A-gYw.mjs} +4 -4
- package/dist/spawn-claims-Dn3C_N6w.mjs +49 -0
- package/dist/{start-CmxtOKjU.mjs → start-DYkkKF0s.mjs} +27 -31
- package/dist/{state-DZobzxLW.mjs → state-NcJzMEBF.mjs} +5 -3
- package/dist/{stats-CLg5RuDS.mjs → stats-B63-JVAY.mjs} +4 -4
- package/dist/{stats-BYcZ6n1h.mjs → stats-DG9e66Rz.mjs} +66 -5
- package/dist/status-S6ehL4Ui.mjs +932 -0
- package/dist/{stop-C8JW6kKp.mjs → stop-BO28HGqF.mjs} +101 -25
- package/dist/{stop-B1kOpYei.mjs → stop-T1R-cZRz.mjs} +2 -2
- package/dist/supervisor-run.mjs +52 -34
- package/dist/{workspace-process-lock-BYfZz_S-.mjs → workspace-process-lock-DWaiRD0e.mjs} +14 -9
- package/dist/{workspace-state-BT5E3SA2.mjs → workspace-state-DF2gCFhx.mjs} +52 -29
- package/dist/worktree-DKhSF0UX.mjs +2 -0
- package/dist/{worktree-CFLA-6MX.mjs → worktree-LGB-UwgG.mjs} +603 -59
- package/dist/{worktree-FG_ZKKdb.mjs → worktree-R_cUlE7s.mjs} +62 -41
- package/dist/{xcode-B6YaWeg0.mjs → xcode-BZqyxh3e.mjs} +216 -58
- package/package.json +5 -6
- package/skill/SKILL.md +2 -0
- package/dist/app-install-BDbsSgCl.mjs +0 -1175
- package/dist/build-slots-C-oAHRT1.mjs +0 -151
- package/dist/dev-client-BmT-ioFI.mjs +0 -797
- package/dist/exec-B29XNuhP.mjs +0 -77
- package/dist/reclaim-KJ-0uWEF.mjs +0 -361
- package/dist/server-expo-YDDG3eP7.mjs +0 -2
- package/dist/status-DdkLki47.mjs +0 -426
- package/dist/{metro-store-CDDZHtPl.mjs → metro-store-DzeWkfqW.mjs} +1 -1
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { r as createNdjsonWriter } from "./ndjson-
|
|
4
|
-
import { _ as
|
|
5
|
-
import {
|
|
6
|
-
import { a as
|
|
7
|
-
import { n as MODE_EXPO, p as writeWorkspaceLaunch, t as MODE_BARE } from "./state-
|
|
8
|
-
import { a as
|
|
9
|
-
import { n as verifyCollectorOwnership } from "./ownership-
|
|
10
|
-
import {
|
|
11
|
-
import { _ as
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { t as withWorkspaceProcessLock } from "./workspace-process-lock-
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { a as
|
|
21
|
-
import { c as
|
|
22
|
-
import { a as
|
|
23
|
-
import {
|
|
24
|
-
import { n as
|
|
1
|
+
import { G as parseDeviceSlotOption, H as deviceSlotKey, J as validateDeviceSlot, V as deviceSlotFileKey, f as getProject, k as ownership_claim_exports, l as getConcurrencyLimits, w as upsertProject } from "./config-Cp9lM3wX.mjs";
|
|
2
|
+
import { t as getExecutor } from "./exec-jIAlgilk.mjs";
|
|
3
|
+
import { r as createNdjsonWriter } from "./ndjson-9uFNRwfe.mjs";
|
|
4
|
+
import { _ as workspaceDir, b as workspaceLogsDir, c as writeWorkspaceState, i as recordWorkspaceUse, r as readWorkspaceState } from "./workspace-state-DF2gCFhx.mjs";
|
|
5
|
+
import { E as removeTemporaryEntry, T as makeTemporaryDirectory, _ as repoRoot, s as gitCommonDir } from "./worktree-R_cUlE7s.mjs";
|
|
6
|
+
import { a as detectIsExpo, i as detectBundleId, n as appProjectProblem, o as findProjectRoot, t as NO_PROJECT_REFUSAL } from "./project-DS112DYB.mjs";
|
|
7
|
+
import { n as MODE_EXPO, p as writeWorkspaceLaunch, t as MODE_BARE } from "./state-NcJzMEBF.mjs";
|
|
8
|
+
import { a as pidExists, c as resolveProjectMetro, l as signalProcessTree } from "./metro-DrLHaMn2.mjs";
|
|
9
|
+
import { n as verifyCollectorOwnership } from "./ownership-D15Op8vN.mjs";
|
|
10
|
+
import { D as remoteIosSetting, F as unknownSettingKeys, J as optimizationBuildProfile, K as artifactCachePolicy, L as REMOTE_DEVICE_BACKENDS, M as settingShapeErrors, O as resolveCacheProviderConfig, P as tunnelModeSetting, W as detectProviders, Y as resolveOptimizations, b as metroWarmupUrlSetting, d as iosLanHostSetting, f as iosLanHostSettingError, g as iosSigningIdentitySha1SettingError, h as iosSigningIdentitySha1Setting, i as SETTING_SHAPE_REMEDY, k as resolveSettings, m as iosSigningIdentitySettingError, p as iosSigningIdentitySetting, u as cacheProviderSettingError, w as publicUrlSetting } from "./settings-D030k0t4.mjs";
|
|
11
|
+
import { _ as stepTimer, c as launchErrorReport, g as stepClock, h as shortUdid, i as formatDuration, l as phaseLine, m as shortHash, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-gByVmIjy.mjs";
|
|
12
|
+
import { S as untrackedNativeFiles, _ as refingerprintAfterMutation, a as waitForBuild, c as describeFingerprintMiss, d as fingerprintDiffRecord, f as fingerprintDiffSuffix, g as providerUploadOutcome, h as providerDownloadPath, m as prepareProviderDownloadDir, o as waitForSharedBuild, p as fingerprintProject, r as releaseBuildLock, s as buildCacheKey, t as acquireBuildLock, u as filesystemBuildCapability, v as resolveBuild, x as untrackedMissLine, y as storeBuild } from "./build-lock-DPXPLgTc.mjs";
|
|
13
|
+
import { S as uploadRemote, _ as loadProjectProvider, b as resolveEasCliBin, d as UPLOAD_TIMEOUT_MS, f as cacheLevel, g as isEasAuthFailureText, h as exitAfterFlush, m as easAuthNote, o as parkedMaxSetting, p as checkEasAuth, t as POOL_SETTING_REMEDY, u as RESOLVE_TIMEOUT_MS, x as resolveRemote } from "./sim-pool-KaIsp2Ft.mjs";
|
|
14
|
+
import { C as isEasBuildFailure, S as easDeviceBuildRemedy, _ as noMetroMessage, a as swapJsBundle, b as sleep, c as ensureBooted, f as clearIosAdoptionPending, g as launchOutcomeRecord, h as isPhysicalDeviceRequest, l as ensureOwnedDevice, m as gateShouldRetry, n as pickDevClientScheme, o as needsPrebuild, p as ensureWorkspaceStorageSafely, r as schemesFromInfoPlist, s as runPrebuild, t as devClientScheme, v as noMetroRemedy, w as resolveEasDevelopmentBuild, x as warmMetro, y as resolveMetroWithRetry } from "./dev-client-HyqISM0h.mjs";
|
|
15
|
+
import { t as withWorkspaceProcessLock } from "./workspace-process-lock-DWaiRD0e.mjs";
|
|
16
|
+
import { n as NO_BUILD_PROGRESS, s as startBuildProgress } from "./build-progress-CVqkfPC6.mjs";
|
|
17
|
+
import { c as readMetroRecords, d as verifyLaunch, f as verifyReleaseLaunch, i as RELEASE_VERIFY_WAIT_MS, l as unverifiedLaunchLines, n as LAUNCH_FATAL, o as isBundleProof, r as LAUNCH_UNVERIFIED, s as readCollectorRecords, t as LAUNCH_BUNDLING } from "./launch-verify-Q_OtW1Rf.mjs";
|
|
18
|
+
import { c as clearOtherUserApps, h as iosAppProcess, m as installIosApp, r as DEFAULT_METRO_PORT, u as devClientUrl, v as launchIosApp } from "./app-install-Uf3a83Tv.mjs";
|
|
19
|
+
import { O as parseIosSimulatorApp, p as listIosRuntimes } from "./ios-BL2NFckr.mjs";
|
|
20
|
+
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-CnTAz8X1.mjs";
|
|
21
|
+
import { a as compilationCacheActivityLine, c as readBundleExecutable, g as acquireBuildSlot, l as readBundleId, p as describeDiagnostic, r as buildIos, s as discoverXcodeProject, t as COMPILATION_CACHE_NOT_RUN, u as resolveScheme, v as releaseBuildSlot } from "./xcode-BZqyxh3e.mjs";
|
|
22
|
+
import { a as statsProjectKey, i as recordRunStats, n as readRunEstimates, t as createRunRecorder } from "./stats-DG9e66Rz.mjs";
|
|
23
|
+
import { c as unknownIosRuntimeRefusal, r as checkDeviceCapacity, s as unknownIosDeviceTypeRefusal } from "./simslim-B_LsGLuJ.mjs";
|
|
24
|
+
import { a as ensureMetroReachable, b as ownedSessionName, c as remoteIosDeps, l as resolveRemoteContext, n as binOnPath, o as ensureRemoteBootOwned, r as bundleEntryPoint, w as gateMetroOrigin } from "./device-remote-AQ5rQPqr.mjs";
|
|
25
|
+
import { n as nativeRunCommand, t as launchSlotScope } from "./slot-launch-DU9A-gYw.mjs";
|
|
25
26
|
import { t as spawnEntry } from "./spawn-entry-nCE6m770.mjs";
|
|
26
|
-
import { a as printNativeCrashReport, n as IOS_CRASH_REPORT_RETRY, o as simulatorConsolePaths, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-
|
|
27
|
-
import { a as
|
|
28
|
-
import { a as runPodInstall, n as podsAreStale, r as readPodState } from "./deps-
|
|
27
|
+
import { a as printNativeCrashReport, n as IOS_CRASH_REPORT_RETRY, o as simulatorConsolePaths, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-Vfz83GCF.mjs";
|
|
28
|
+
import { a as iosPoolCandidates, c as listIosDevices, d as verifyIosDeviceReleaseLaunch, i as iosDeviceProcess, l as localNetworkPending, n as installIosDeviceApp, o as iosPoolNoCandidatesRefusal, r as iosDeviceBounds, s as isWirelessIosDevice, t as awaitIosDeviceLaunch, u as resolveIosPhysicalDevice } from "./ios-device-D972i9wf.mjs";
|
|
29
|
+
import { a as runPodInstall, n as podsAreStale, r as readPodState } from "./deps-Cip5vUm1.mjs";
|
|
29
30
|
import { existsSync, mkdirSync, mkdtempSync, openSync, rmSync, writeFileSync } from "node:fs";
|
|
30
31
|
import { InvalidArgumentError } from "commander";
|
|
31
|
-
import { X509Certificate } from "node:crypto";
|
|
32
32
|
import { basename, join } from "node:path";
|
|
33
|
+
import { X509Certificate } from "node:crypto";
|
|
33
34
|
import { networkInterfaces, tmpdir } from "node:os";
|
|
34
|
-
import { createWarnOnce, loadCacheProvider, resolveTieredBuild, storeTieredBuild } from "@stim-cli/cache";
|
|
35
35
|
import chalk from "chalk";
|
|
36
|
+
import { createWarnOnce, loadCacheProvider, resolveTieredBuild, storeTieredBuild } from "@stim-cli/cache";
|
|
36
37
|
//#region src/engine/ios-lan.ts
|
|
37
38
|
const IP_TXT = "ip.txt";
|
|
38
39
|
function chooseLanAddress({ pinned = null, candidates }) {
|
|
@@ -91,6 +92,7 @@ function copyAppAside(appPath, { exec = null, mkdtemp = () => makeTemporaryDirec
|
|
|
91
92
|
]);
|
|
92
93
|
} catch {
|
|
93
94
|
try {
|
|
95
|
+
removeTemporaryEntry(copy);
|
|
94
96
|
e.runFile("cp", [
|
|
95
97
|
"-R",
|
|
96
98
|
appPath,
|
|
@@ -170,7 +172,7 @@ function deviceModelRefusal({ slot, deviceTypeFlag, runtimeFlag, deviceType, run
|
|
|
170
172
|
if (typeof deviceTypeFlag === "string" && deviceTypeFlag.trim() === "") return {
|
|
171
173
|
code: "STIM_BAD_ARG",
|
|
172
174
|
message: "--device-type was given an empty name.",
|
|
173
|
-
remedy: "Pass `--device-type <name>` with a model `xcrun simctl list devicetypes` names, e.g. \"iPad Pro 13-inch (
|
|
175
|
+
remedy: "Pass `--device-type <name>` with a model `xcrun simctl list devicetypes` names, e.g. \"iPad Pro 13-inch (M5)\"."
|
|
174
176
|
};
|
|
175
177
|
if (typeof runtimeFlag === "string" && runtimeFlag.trim() === "") return {
|
|
176
178
|
code: "STIM_BAD_ARG",
|
|
@@ -383,7 +385,7 @@ var ArtifactRefusal = class extends Error {
|
|
|
383
385
|
}
|
|
384
386
|
};
|
|
385
387
|
async function acquireIosArtifact({ root, logFile, udid, remoteDestination, device, configuration, buildScheme, buildProfile, isExpo, optimizations, cache, easBuild, easProfile, maxBuilds, progress }, d) {
|
|
386
|
-
const { phase, note, logWriter, estimates, stats } = progress;
|
|
388
|
+
const { phase, note, logWriter, estimates, stats, step } = progress;
|
|
387
389
|
const physical = device !== null;
|
|
388
390
|
const lanAddress = device?.lanAddress ?? null;
|
|
389
391
|
const metroPort = device?.metroPort ?? null;
|
|
@@ -481,6 +483,7 @@ async function acquireIosArtifact({ root, logFile, udid, remoteDestination, devi
|
|
|
481
483
|
}
|
|
482
484
|
return;
|
|
483
485
|
}
|
|
486
|
+
step("cache-lookup");
|
|
484
487
|
const fingerprintTimer = stepTimer(d.now);
|
|
485
488
|
let computedFingerprint;
|
|
486
489
|
try {
|
|
@@ -605,107 +608,40 @@ async function acquireIosArtifact({ root, logFile, udid, remoteDestination, devi
|
|
|
605
608
|
}
|
|
606
609
|
return remote;
|
|
607
610
|
}
|
|
608
|
-
async function
|
|
609
|
-
if (!useBuildCache) return;
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
note(chalk.yellow(phaseLine("build", `could not take the build lock: ${e?.message || e}; building anyway`)));
|
|
611
|
+
async function awaitSharedBuild() {
|
|
612
|
+
if (!useBuildCache || appPath) return;
|
|
613
|
+
const shared = await waitForSharedBuild({
|
|
614
|
+
platform: "ios",
|
|
615
|
+
key: cacheKey,
|
|
616
|
+
fingerprint,
|
|
617
|
+
root,
|
|
618
|
+
logFile,
|
|
619
|
+
command: "stim ios",
|
|
620
|
+
acquire: d.acquireBuildLock,
|
|
621
|
+
wait: d.waitForBuild,
|
|
622
|
+
now: d.now,
|
|
623
|
+
phase: (text) => {
|
|
624
|
+
step("wait");
|
|
625
|
+
phase("build", text);
|
|
626
|
+
},
|
|
627
|
+
warn: (text) => note(chalk.yellow(phaseLine("build", text))),
|
|
628
|
+
out: note
|
|
629
|
+
});
|
|
630
|
+
if (shared.refusal) fail({
|
|
631
|
+
...shared.refusal,
|
|
632
|
+
build: {
|
|
633
|
+
fingerprint,
|
|
634
|
+
cacheKey,
|
|
635
|
+
cacheHit,
|
|
636
|
+
cacheSkipped: !useBuildCache
|
|
635
637
|
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
const held = attempt.held;
|
|
644
|
-
const who = held.projectRoot || "another workspace";
|
|
645
|
-
phase("build", `${who} is already building ${shortHash(fingerprint)} (pid ${held.pid})${held.logFile ? ` -- tail ${held.logFile}` : ""} -- stim guide lifecycle concurrency`);
|
|
646
|
-
let waited = null;
|
|
647
|
-
try {
|
|
648
|
-
const ceilingMs = WAIT_CEILING_MS - (d.now() - waitStarted);
|
|
649
|
-
if (ceilingMs <= 0) throw Object.assign(/* @__PURE__ */ new Error(`Waited ${formatDuration(d.now() - waitStarted)} for shared builds without an artifact; ${who} (pid ${held.pid}) holds ${attempt.path}.`), {
|
|
650
|
-
code: "STIM_BUILD_WAIT_TIMEOUT",
|
|
651
|
-
lockPath: attempt.path
|
|
652
|
-
});
|
|
653
|
-
waited = await d.waitForBuild({
|
|
654
|
-
platform: "ios",
|
|
655
|
-
key: cacheKey,
|
|
656
|
-
out: note,
|
|
657
|
-
ceilingMs
|
|
658
|
-
});
|
|
659
|
-
} catch (e) {
|
|
660
|
-
const refusal = (0, ownership_claim_exports.claimFailure)(e, "stim ios");
|
|
661
|
-
if (refusal) fail({
|
|
662
|
-
code: refusal.code,
|
|
663
|
-
message: refusal.message,
|
|
664
|
-
remedy: refusal.remedy,
|
|
665
|
-
build: {
|
|
666
|
-
fingerprint,
|
|
667
|
-
cacheKey,
|
|
668
|
-
cacheHit,
|
|
669
|
-
cacheSkipped: !useBuildCache
|
|
670
|
-
}
|
|
671
|
-
});
|
|
672
|
-
const err = e;
|
|
673
|
-
if (err?.code !== "STIM_BUILD_WAIT_TIMEOUT") throw e;
|
|
674
|
-
fail({
|
|
675
|
-
code: "STIM_BUILD_WAIT_TIMEOUT",
|
|
676
|
-
message: err.message,
|
|
677
|
-
remedy: `Check pid ${held.pid}; if it is not really building, remove ${err.lockPath} and run \`stim ios\` again.`,
|
|
678
|
-
build: {
|
|
679
|
-
fingerprint,
|
|
680
|
-
cacheKey,
|
|
681
|
-
cacheHit,
|
|
682
|
-
cacheSkipped: !useBuildCache
|
|
683
|
-
}
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
if (waited?.hit) {
|
|
687
|
-
appPath = waited.hit ?? null;
|
|
688
|
-
cacheHit = "local";
|
|
689
|
-
waitedForBuild = {
|
|
690
|
-
pid: held.pid,
|
|
691
|
-
ms: waited.waitedMs
|
|
692
|
-
};
|
|
693
|
-
phase("build", `waited ${formatDuration(waited.waitedMs)} for ${who}'s build -> installed from cache -- stim guide lifecycle concurrency`);
|
|
694
|
-
} else if (waited?.lockReleased) {
|
|
695
|
-
failedHolder = void 0;
|
|
696
|
-
releasedWait = {
|
|
697
|
-
facts: {
|
|
698
|
-
pid: held.pid,
|
|
699
|
-
ms: waited.waitedMs
|
|
700
|
-
},
|
|
701
|
-
who
|
|
702
|
-
};
|
|
703
|
-
phase("build", `${who}'s build lock was released; rechecking this workspace before building`);
|
|
704
|
-
} else {
|
|
705
|
-
note(chalk.yellow(phaseLine("build", `${who}'s build ended without an artifact (${waited?.builderFailed}); retrying the build lock`)));
|
|
706
|
-
failedHolder = held;
|
|
707
|
-
}
|
|
708
|
-
} else break;
|
|
638
|
+
});
|
|
639
|
+
buildLock = shared.lock;
|
|
640
|
+
releasedWait = shared.released;
|
|
641
|
+
if (shared.hit) {
|
|
642
|
+
appPath = shared.hit.path;
|
|
643
|
+
cacheHit = "local";
|
|
644
|
+
waitedForBuild = shared.hit.waited;
|
|
709
645
|
}
|
|
710
646
|
}
|
|
711
647
|
const prepareDeviceApp = async (path, { fresh }) => {
|
|
@@ -827,6 +763,7 @@ async function acquireIosArtifact({ root, logFile, udid, remoteDestination, devi
|
|
|
827
763
|
}
|
|
828
764
|
const mutatingSteps = [];
|
|
829
765
|
if (d.needsPrebuild(root, "ios", isExpo)) {
|
|
766
|
+
step("prebuild");
|
|
830
767
|
const result = await d.runPrebuild(root, "ios", logWriter());
|
|
831
768
|
if (result?.failed) {
|
|
832
769
|
phase("prebuild", "FAILED");
|
|
@@ -844,6 +781,7 @@ async function acquireIosArtifact({ root, logFile, udid, remoteDestination, devi
|
|
|
844
781
|
const podState = d.readPodState(root);
|
|
845
782
|
const action = podAction(podState, d.podsAreStale(podState.lockText, podState.manifestText));
|
|
846
783
|
if (action.install) {
|
|
784
|
+
step("pods");
|
|
847
785
|
const result = await d.runPodInstall(root, logWriter(), { estimateMs: estimates().podsMs });
|
|
848
786
|
const podCommand = result?.command || "pod install";
|
|
849
787
|
for (const line of result?.notes || []) note(chalk.dim(phaseLine("pods", line)));
|
|
@@ -903,6 +841,7 @@ async function acquireIosArtifact({ root, logFile, udid, remoteDestination, devi
|
|
|
903
841
|
}
|
|
904
842
|
}
|
|
905
843
|
if (!appPath) {
|
|
844
|
+
step("compile");
|
|
906
845
|
phase("build", `compiling ${configuration || "Debug"} with xcodebuild`);
|
|
907
846
|
const result = await d.buildIos({
|
|
908
847
|
root,
|
|
@@ -977,7 +916,7 @@ async function acquireIosArtifact({ root, logFile, udid, remoteDestination, devi
|
|
|
977
916
|
await resolveInitialFingerprint();
|
|
978
917
|
if (!easBuild) {
|
|
979
918
|
remote = await resolveRemoteArtifact();
|
|
980
|
-
await
|
|
919
|
+
await awaitSharedBuild();
|
|
981
920
|
await prepareCachedArtifact();
|
|
982
921
|
await buildArtifact();
|
|
983
922
|
}
|
|
@@ -1229,7 +1168,7 @@ function profileGate(input) {
|
|
|
1229
1168
|
if (!input.profile) return {
|
|
1230
1169
|
ok: false,
|
|
1231
1170
|
code: SIGNING_CODES.noProfile,
|
|
1232
|
-
reason: "`
|
|
1171
|
+
reason: "`openssl smime` could not decode the app bundle's embedded.mobileprovision.",
|
|
1233
1172
|
remedy: `The profile inside the app is corrupt. Delete the build cache entry with \`stim gc --delete\`, then ${XCODE_STEP}`
|
|
1234
1173
|
};
|
|
1235
1174
|
const profile = input.profile;
|
|
@@ -1335,10 +1274,13 @@ function readEmbeddedProfile(appPath, { exec = null } = {}) {
|
|
|
1335
1274
|
try {
|
|
1336
1275
|
return {
|
|
1337
1276
|
present: true,
|
|
1338
|
-
profile: parseProvisioningProfilePlist(executor.runFile("
|
|
1339
|
-
"
|
|
1340
|
-
"-
|
|
1341
|
-
"-
|
|
1277
|
+
profile: parseProvisioningProfilePlist(executor.runFile("/usr/bin/openssl", [
|
|
1278
|
+
"smime",
|
|
1279
|
+
"-verify",
|
|
1280
|
+
"-noverify",
|
|
1281
|
+
"-inform",
|
|
1282
|
+
"DER",
|
|
1283
|
+
"-in",
|
|
1342
1284
|
path
|
|
1343
1285
|
], { timeoutMs: SIGNING_TIMEOUT_MS }))
|
|
1344
1286
|
};
|
|
@@ -1624,7 +1566,6 @@ const DEFAULT_DEPS = {
|
|
|
1624
1566
|
devClientScheme,
|
|
1625
1567
|
getProject,
|
|
1626
1568
|
upsertProject,
|
|
1627
|
-
projectShortcut,
|
|
1628
1569
|
checkDeviceCapacity,
|
|
1629
1570
|
ensureOwnedDevice,
|
|
1630
1571
|
listIosRuntimes,
|
|
@@ -1838,6 +1779,12 @@ function reportLaunchErrors(errors, note, root) {
|
|
|
1838
1779
|
for (const line of report.lines) note(chalk.yellow(phaseLine("launch", line)));
|
|
1839
1780
|
return report.lines.length > 0;
|
|
1840
1781
|
}
|
|
1782
|
+
function installsOverWifi(d, udid, selectedWireless, note) {
|
|
1783
|
+
const current = d.listIosDevices().find((entry) => entry.udid === udid);
|
|
1784
|
+
const wireless = current ? isWirelessIosDevice(current) : selectedWireless;
|
|
1785
|
+
if (wireless) note(phaseLine("device", `${current?.name ?? udid} is paired over Wi-Fi, so the install and launch go over the network and take longer than over a cable`));
|
|
1786
|
+
return wireless;
|
|
1787
|
+
}
|
|
1841
1788
|
function cleanAdoptedIosApps({ d, root, slot, udid, bundleId, phase, note }) {
|
|
1842
1789
|
const swept = d.clearOtherUserApps({
|
|
1843
1790
|
udid,
|
|
@@ -1878,7 +1825,7 @@ function recordIosReloadTarget({ d, root, physical, remoteDevice, bundleId, udid
|
|
|
1878
1825
|
function simulatorLaunchFailureRemedy(remote, udid, bundleId, logFile) {
|
|
1879
1826
|
return `${remote ? "Run" : "If the simulator timed out, run `stim doctor --platform ios` and resolve any reported host memory pressure before retrying. Otherwise run"} \`xcrun simctl launch --terminate-running-process --console ${udid} ${bundleId}\` to see what the app reports, and check ${logFile}.`;
|
|
1880
1827
|
}
|
|
1881
|
-
async function finishIosRun({ artifact, d, root, slot, json, release, configuration, buildScheme, isExpo, metroCheck, metroPort, logsDir, logFile, device, udid, physical, lanAddress, lanOriginUrl, remoteDevice, bootPromise, bootDuration, fail, phase, note, logWriter, elapsed, startedAt, closeWriter, lease, releaseLease, recordRun }) {
|
|
1828
|
+
async function finishIosRun({ artifact, d, root, slot, json, release, configuration, buildScheme, isExpo, metroCheck, metroPort, logsDir, logFile, device, udid, physical, wireless, lanAddress, lanOriginUrl, remoteDevice, bootPromise, bootDuration, fail, phase, note, logWriter, elapsed, startedAt, closeWriter, lease, releaseLease, recordRun, enterPhase }) {
|
|
1882
1829
|
const { path: appPath, bundleId: initialBundleId, failureFields: buildFailure, cache } = artifact;
|
|
1883
1830
|
const { hit: cacheHit, providerName, readEnabled: useBuildCache, waitedForBuild, compilation: compilationCache } = cache;
|
|
1884
1831
|
const storeHash = cache.identity?.fingerprint ?? null;
|
|
@@ -1918,6 +1865,7 @@ async function finishIosRun({ artifact, d, root, slot, json, release, configurat
|
|
|
1918
1865
|
}
|
|
1919
1866
|
});
|
|
1920
1867
|
if (bundleId) d.upsertProject(root, { bundleId });
|
|
1868
|
+
enterPhase("install");
|
|
1921
1869
|
const booted = await bootPromise;
|
|
1922
1870
|
if (!booted?.ok) return fail({
|
|
1923
1871
|
code: booted?.code || "STIM_NO_DEVICE",
|
|
@@ -1934,7 +1882,9 @@ async function finishIosRun({ artifact, d, root, slot, json, release, configurat
|
|
|
1934
1882
|
let launched = null;
|
|
1935
1883
|
let launchedAt = d.now();
|
|
1936
1884
|
if (physical) {
|
|
1937
|
-
const
|
|
1885
|
+
const overWifi = installsOverWifi(d, udid, wireless, note);
|
|
1886
|
+
const bounds = iosDeviceBounds(overWifi);
|
|
1887
|
+
const lostBeforeInstall = raiseLeaseFor(bounds.installMs, true);
|
|
1938
1888
|
if (lostBeforeInstall) return fail(lostBeforeInstall);
|
|
1939
1889
|
await d.stopPreviousCollector({
|
|
1940
1890
|
root,
|
|
@@ -1944,8 +1894,9 @@ async function finishIosRun({ artifact, d, root, slot, json, release, configurat
|
|
|
1944
1894
|
const installed = d.installIosDeviceApp({
|
|
1945
1895
|
udid,
|
|
1946
1896
|
appPath,
|
|
1947
|
-
bundleId
|
|
1948
|
-
|
|
1897
|
+
bundleId,
|
|
1898
|
+
wireless: overWifi
|
|
1899
|
+
}, { beforeStep: () => raiseLeaseFor(bounds.installMs, false) });
|
|
1949
1900
|
if (installed?.failed) {
|
|
1950
1901
|
dropSwapDir();
|
|
1951
1902
|
return fail({
|
|
@@ -1970,8 +1921,9 @@ async function finishIosRun({ artifact, d, root, slot, json, release, configurat
|
|
|
1970
1921
|
});
|
|
1971
1922
|
}
|
|
1972
1923
|
dropSwapDir();
|
|
1973
|
-
raiseLeaseFor(COLLECTOR_EXIT_WAIT_MS +
|
|
1924
|
+
raiseLeaseFor(COLLECTOR_EXIT_WAIT_MS + bounds.launchMs, false);
|
|
1974
1925
|
const payloadUrl = scheme && metroPort !== null && lanAddress ? devClientUrl(scheme, metroPort, lanAddress) : null;
|
|
1926
|
+
enterPhase("launch");
|
|
1975
1927
|
const launchTimer = stepTimer(d.now);
|
|
1976
1928
|
launchedAt = d.now();
|
|
1977
1929
|
logWriter().write({
|
|
@@ -2012,10 +1964,11 @@ async function finishIosRun({ artifact, d, root, slot, json, release, configurat
|
|
|
2012
1964
|
bundleId,
|
|
2013
1965
|
appName: appName ?? bundleId,
|
|
2014
1966
|
collectorPid: collector.pid,
|
|
1967
|
+
wireless: overWifi,
|
|
2015
1968
|
readRecords: () => readCollectorRecords(logsDir).filter((entry) => Number(entry.ts) >= launchedAt && (entry.slot ?? "default") === (slot ?? "default"))
|
|
2016
1969
|
});
|
|
2017
1970
|
if (started.failed || !started.pid) return fail({
|
|
2018
|
-
code: "STIM_LAUNCH_FAILED",
|
|
1971
|
+
code: started.code ?? "STIM_LAUNCH_FAILED",
|
|
2019
1972
|
message: started.reason ?? `${bundleId} did not start on ${udid}.`,
|
|
2020
1973
|
remedy: started.remedy ?? null,
|
|
2021
1974
|
lines: started.lines ?? [],
|
|
@@ -2088,6 +2041,7 @@ async function finishIosRun({ artifact, d, root, slot, json, release, configurat
|
|
|
2088
2041
|
appExecutable,
|
|
2089
2042
|
note
|
|
2090
2043
|
});
|
|
2044
|
+
enterPhase("launch");
|
|
2091
2045
|
const launchTimer = stepTimer(d.now);
|
|
2092
2046
|
launchedAt = d.now();
|
|
2093
2047
|
logWriter().write({
|
|
@@ -2257,18 +2211,33 @@ function iosCommand(program) {
|
|
|
2257
2211
|
registerIos(program);
|
|
2258
2212
|
}
|
|
2259
2213
|
function registerIos(program, deps = {}) {
|
|
2260
|
-
program.command("ios").description("Build (or restore from the fingerprint cache), install and launch this workspace's app on its owned simulator, wired to the reserved Metro port. Requires a running dev server (`stim start`).").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)",
|
|
2214
|
+
program.command("ios").description("Build (or restore from the fingerprint cache), install and launch this workspace's app on its owned simulator, wired to the reserved Metro port. Requires a running dev server (`stim start`).").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("--json", "Emit the facts as a single JSON line on stdout; every other line goes to stderr").option("--scheme <name>", "Shared Xcode app scheme to build; overrides automatic scheme selection, not the app URL scheme").option("--no-metro-check", "Skip the \"is this workspace's dev server running?\" gate and build anyway").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("--configuration <name>", "Xcode configuration to build (e.g. Release). A non-Debug configuration embeds the JS bundle and skips Metro entirely. Overrides the ios.configuration setting. Default: Debug").option("--device-type <name>", "Simulator model to create this workspace's owned sim as, exactly as `xcrun simctl list devicetypes` names it (e.g. \"iPad Pro 13-inch (M5)\"). Overrides the ios.deviceType setting for this invocation. A model no installed runtime can create refuses with STIM_BAD_ARG and prints the models they do offer.").option("--runtime <version>", "Simulator runtime to create this workspace's owned sim on, as a version (\"18.5\") or a runtime's full name (\"iOS 18.5\"); nothing else matches. Overrides the ios.runtime setting for this invocation. An unknown version refuses with STIM_BAD_ARG and prints the installed runtimes.").option("--simulator-app <app>", "Open the owned simulator in xcode, siniulator, or stim-desktop for this run, overriding the machine iosSimulatorApp setting. Also opens an already running simulator; local simulators only.").option("--device [udid]", "Build the iphoneos slice for a connected iPhone, install it, and launch it, instead of using this workspace's owned simulator. The phone can be cabled or paired over Wi-Fi. With no UDID, the first cabled device this workspace can lease is used, waiting for one that is busy; a Wi-Fi device is used only when no cabled one is connected and ready. In Debug the app is wired to this workspace's Metro over the LAN. Stim never creates, boots, or deletes a physical device.").option("--remote <backend>", "Install and launch on a remote device with proxy or EAS. Builds are local unless --eas-profile selects an existing EAS build.", (value) => {
|
|
2261
2215
|
if (REMOTE_DEVICE_BACKENDS.includes(value)) return value;
|
|
2262
2216
|
throw new InvalidArgumentError(`expected one of: ${REMOTE_DEVICE_BACKENDS.join(", ")}`);
|
|
2263
2217
|
}).option("--wait <seconds>", "How long to wait for another workspace to release the phone it leases, before refusing with STIM_DEVICE_BUSY (default 60, 0 refuses at once). Only with --device.").option("--no-wait", "Install on a phone 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. Only with --device.").action(async (opts) => {
|
|
2264
2218
|
const root = (deps.findProjectRoot ?? DEFAULT_DEPS.findProjectRoot)(process.cwd());
|
|
2265
|
-
const run = () => runIos({
|
|
2219
|
+
const run = (progress) => runIos({
|
|
2266
2220
|
...opts,
|
|
2267
2221
|
waitConflict: waitFlagConflict(process.argv)
|
|
2268
|
-
}, deps);
|
|
2269
|
-
const completion = root ? await withWorkspaceProcessLock(workspaceDir(root), "native-run",
|
|
2222
|
+
}, deps, progress);
|
|
2223
|
+
const completion = root ? await withWorkspaceProcessLock(workspaceDir(root), "native-run", async (claim) => {
|
|
2224
|
+
recordWorkspaceUse(root);
|
|
2225
|
+
const progress = startBuildProgress({
|
|
2226
|
+
root,
|
|
2227
|
+
platform: "ios",
|
|
2228
|
+
slot: opts.slot ?? "default",
|
|
2229
|
+
claim,
|
|
2230
|
+
note: (line) => writeNote(chalk.dim(line))
|
|
2231
|
+
});
|
|
2232
|
+
try {
|
|
2233
|
+
return await run(progress);
|
|
2234
|
+
} finally {
|
|
2235
|
+
progress.clear();
|
|
2236
|
+
}
|
|
2237
|
+
}, {
|
|
2270
2238
|
external: true,
|
|
2271
|
-
waitMs: 18e5
|
|
2239
|
+
waitMs: 18e5,
|
|
2240
|
+
declareSpawns: true
|
|
2272
2241
|
}) : await run();
|
|
2273
2242
|
if (!completion) process.exit(1);
|
|
2274
2243
|
else if (completion.uploadsAbandoned) exitAfterFlush(0);
|
|
@@ -2332,7 +2301,7 @@ function iosSlotDeps(d, slot) {
|
|
|
2332
2301
|
}
|
|
2333
2302
|
return d;
|
|
2334
2303
|
}
|
|
2335
|
-
async function runIos(opts = {}, overrides = {}) {
|
|
2304
|
+
async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
|
|
2336
2305
|
const slot = validateDeviceSlot(opts.slot);
|
|
2337
2306
|
let d = iosSlotDeps({
|
|
2338
2307
|
...DEFAULT_DEPS,
|
|
@@ -2346,16 +2315,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2346
2315
|
const started = d.now();
|
|
2347
2316
|
const startedAt = new Date(started).toISOString();
|
|
2348
2317
|
const elapsed = () => d.now() - started;
|
|
2349
|
-
const
|
|
2350
|
-
if (!foundRoot) {
|
|
2351
|
-
note(chalk.red("Not in a React Native project (no package.json found)."));
|
|
2352
|
-
process.exitCode = 1;
|
|
2353
|
-
return null;
|
|
2354
|
-
}
|
|
2355
|
-
const root = foundRoot;
|
|
2356
|
-
const projectProblem = appProjectProblem(root);
|
|
2357
|
-
if (projectProblem) {
|
|
2358
|
-
const { message, remedy } = projectProblem;
|
|
2318
|
+
const refuseProject = ({ message, remedy }) => {
|
|
2359
2319
|
note(chalk.red(phaseLine("error", message)));
|
|
2360
2320
|
note(chalk.dim(phaseLine("remedy", remedy)));
|
|
2361
2321
|
note(chalk.red(phaseLine("failed", "STIM_NO_PROJECT")));
|
|
@@ -2366,7 +2326,12 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2366
2326
|
}));
|
|
2367
2327
|
process.exitCode = 1;
|
|
2368
2328
|
return null;
|
|
2369
|
-
}
|
|
2329
|
+
};
|
|
2330
|
+
const foundRoot = d.findProjectRoot(process.cwd());
|
|
2331
|
+
if (!foundRoot) return refuseProject(NO_PROJECT_REFUSAL);
|
|
2332
|
+
const root = foundRoot;
|
|
2333
|
+
const projectProblem = appProjectProblem(root);
|
|
2334
|
+
if (projectProblem) return refuseProject(projectProblem);
|
|
2370
2335
|
try {
|
|
2371
2336
|
await d.ensureWorkspaceStorage(root, { note });
|
|
2372
2337
|
} catch (error) {
|
|
@@ -2404,7 +2369,8 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2404
2369
|
platform: "ios",
|
|
2405
2370
|
write: (statsRun, at) => d.recordStats(statsRun, at),
|
|
2406
2371
|
now: () => d.now(),
|
|
2407
|
-
note: (line) => note(chalk.dim(line))
|
|
2372
|
+
note: (line) => note(chalk.dim(line)),
|
|
2373
|
+
phases: () => progress.durations()
|
|
2408
2374
|
});
|
|
2409
2375
|
const recordRun = stats.record;
|
|
2410
2376
|
let compilationCache = COMPILATION_CACHE_NOT_RUN;
|
|
@@ -2477,12 +2443,6 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2477
2443
|
for (const key of unknownSettingKeys(settings)) note(phaseLine("setting", chalk.yellow(`Warning: setting "${key}" is not read by Stim and will be ignored.`)));
|
|
2478
2444
|
const cacheProviderError = cacheProviderSettingError(settings);
|
|
2479
2445
|
if (cacheProviderError) note(chalk.yellow(phaseLine("cache", `${cacheProviderError} Using the local cache.`)));
|
|
2480
|
-
const remoteSettingError = remoteDeviceSettingError(settings);
|
|
2481
|
-
if (remoteSettingError) return fail({
|
|
2482
|
-
code: "STIM_BAD_ARG",
|
|
2483
|
-
message: remoteSettingError,
|
|
2484
|
-
remedy: `Set ios.remote and android.remote to one of: ${REMOTE_DEVICE_BACKENDS.join(", ")}.`
|
|
2485
|
-
});
|
|
2486
2446
|
const poolError = parkedMaxSetting("ios").error;
|
|
2487
2447
|
if (poolError) return fail({
|
|
2488
2448
|
code: "STIM_BAD_ARG",
|
|
@@ -2514,7 +2474,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2514
2474
|
});
|
|
2515
2475
|
if (physical && opts.remote) return fail({
|
|
2516
2476
|
code: "STIM_BAD_ARG",
|
|
2517
|
-
message: "--device builds for a phone
|
|
2477
|
+
message: "--device builds for a phone connected to this machine, and --remote installs on a remote one.",
|
|
2518
2478
|
remedy: "Pass only one of --device and --remote."
|
|
2519
2479
|
});
|
|
2520
2480
|
const noWait = opts.wait === false;
|
|
@@ -2571,12 +2531,10 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2571
2531
|
});
|
|
2572
2532
|
if (remoteBackend !== "eas") registerProject();
|
|
2573
2533
|
const proj = d.getProject(root);
|
|
2574
|
-
const label = d.projectShortcut(root, proj);
|
|
2575
2534
|
let remoteDevice = null;
|
|
2576
2535
|
if (remoteBackend) {
|
|
2577
2536
|
const resolved = await d.resolveRemoteContext({
|
|
2578
2537
|
root,
|
|
2579
|
-
label,
|
|
2580
2538
|
backend: remoteBackend,
|
|
2581
2539
|
easBin: d.resolveEasCliBin(root)?.file ?? null
|
|
2582
2540
|
});
|
|
@@ -2597,6 +2555,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2597
2555
|
}
|
|
2598
2556
|
const limits = d.getConcurrencyLimits();
|
|
2599
2557
|
let physicalDevice = null;
|
|
2558
|
+
let wireless = false;
|
|
2600
2559
|
if (physical && typeof deviceFlag !== "string") {
|
|
2601
2560
|
const pooled = await d.selectFromPool({
|
|
2602
2561
|
root,
|
|
@@ -2604,7 +2563,8 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2604
2563
|
idLabel: "udid",
|
|
2605
2564
|
list: () => iosPoolCandidates(d.listIosDevices()).map((entry) => ({
|
|
2606
2565
|
id: entry.udid,
|
|
2607
|
-
name: entry.name
|
|
2566
|
+
name: entry.name,
|
|
2567
|
+
fallback: isWirelessIosDevice(entry)
|
|
2608
2568
|
})),
|
|
2609
2569
|
noCandidates: () => {
|
|
2610
2570
|
const resolved = iosPoolNoCandidatesRefusal(d.listIosDevices());
|
|
@@ -2628,6 +2588,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2628
2588
|
udid: pooled.candidate.id,
|
|
2629
2589
|
name: pooled.candidate.name ?? pooled.candidate.id
|
|
2630
2590
|
};
|
|
2591
|
+
wireless = pooled.candidate.fallback === true;
|
|
2631
2592
|
} else if (physical) {
|
|
2632
2593
|
const resolved = resolveIosPhysicalDevice(typeof deviceFlag === "string" ? deviceFlag : null, d.listIosDevices());
|
|
2633
2594
|
if (!resolved.udid) return fail({
|
|
@@ -2639,6 +2600,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2639
2600
|
udid: resolved.udid,
|
|
2640
2601
|
name: resolved.name ?? resolved.udid
|
|
2641
2602
|
};
|
|
2603
|
+
wireless = resolved.wireless === true;
|
|
2642
2604
|
}
|
|
2643
2605
|
if (!physical) {
|
|
2644
2606
|
const capacity = d.checkDeviceCapacity({
|
|
@@ -2814,6 +2776,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2814
2776
|
boot,
|
|
2815
2777
|
createdSessionId: remoteDevice.createdSessionId,
|
|
2816
2778
|
abandonCreatedSession: remoteDevice.abandonCreatedSession,
|
|
2779
|
+
webPreviewUrl: remoteDevice.webPreviewUrl,
|
|
2817
2780
|
writeState: d.writeWorkspaceState,
|
|
2818
2781
|
register: registerProject
|
|
2819
2782
|
}) : boot()).then((result) => {
|
|
@@ -2850,7 +2813,8 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2850
2813
|
note,
|
|
2851
2814
|
logWriter,
|
|
2852
2815
|
estimates,
|
|
2853
|
-
stats
|
|
2816
|
+
stats,
|
|
2817
|
+
step: progress.step
|
|
2854
2818
|
}
|
|
2855
2819
|
}, d);
|
|
2856
2820
|
if (!acquiredArtifact.ok) {
|
|
@@ -2868,7 +2832,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2868
2832
|
idLabel: "udid",
|
|
2869
2833
|
waitSeconds,
|
|
2870
2834
|
noWait,
|
|
2871
|
-
installBoundMs:
|
|
2835
|
+
installBoundMs: iosDeviceBounds(wireless).installMs,
|
|
2872
2836
|
appId: artifact.bundleId ?? proj?.bundleId ?? null,
|
|
2873
2837
|
holderAppId: (holder) => d.getProject(holder)?.bundleId ?? null,
|
|
2874
2838
|
now: d.now,
|
|
@@ -2908,6 +2872,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2908
2872
|
device,
|
|
2909
2873
|
udid,
|
|
2910
2874
|
physical,
|
|
2875
|
+
wireless,
|
|
2911
2876
|
lanAddress,
|
|
2912
2877
|
lanOriginUrl,
|
|
2913
2878
|
remoteDevice,
|
|
@@ -2923,7 +2888,8 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2923
2888
|
closeWriter: () => writer?.close?.(),
|
|
2924
2889
|
lease: leaseHandle,
|
|
2925
2890
|
releaseLease,
|
|
2926
|
-
recordRun
|
|
2891
|
+
recordRun,
|
|
2892
|
+
enterPhase: progress.step
|
|
2927
2893
|
});
|
|
2928
2894
|
} finally {
|
|
2929
2895
|
releaseLease();
|