stim 1.18.0 → 1.19.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 +1 -1
- package/dist/{activity-BxnkDZDi.mjs → activity-BSw0x84R.mjs} +3 -3
- package/dist/{agent-device-usage-output-CZ66YA4T.mjs → agent-device-usage-output-Bjxu_VmX.mjs} +5 -5
- package/dist/{android-BvwuMUJ9.mjs → android-BXc6BmEi.mjs} +507 -347
- package/dist/{android-DC3ZLuw0.mjs → android-BdQC6zs1.mjs} +6 -6
- package/dist/{android-BKA16DTf.mjs → android-BvV1gGdN.mjs} +3 -3
- package/dist/{android-CBwCNicO.mjs → android-DE5g_5gv.mjs} +2 -2
- package/dist/{android-cas-BBFyr9CA.mjs → android-cas-C87geAg-.mjs} +3 -3
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/{api-D0VtFhqk.mjs → api-DIf_s86s.mjs} +5 -7
- package/dist/api-run.mjs +8 -8
- package/dist/api.d.mts +8 -2
- package/dist/api.mjs +1 -1
- package/dist/{app-install-D-PUENug.mjs → app-install-CFI4ptUL.mjs} +33 -13
- package/dist/{web-DTU0uiWj.mjs → browser-web-CDhqQxhv.mjs} +134 -172
- package/dist/{budget-DIhL2BKx.mjs → budget-Dz-kyXLv.mjs} +15 -202
- package/dist/{build-facts-DcLv2HSd.d.mts → build-facts-B87vo-Im.d.mts} +32 -1
- package/dist/{cache-manifest-BI7ozfmH.mjs → cache-manifest-DiwKSyv9.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{chrome-DJnmnS5q.mjs → chrome-BTUOo8p2.mjs} +1 -1
- package/dist/{cli-DNJMwADx.mjs → cli-C9Zvgbdc.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/{client-DzhapoMB.mjs → client-CuUo8Nvg.mjs} +248 -23
- package/dist/collector-run.d.mts +6 -0
- package/dist/collector-run.mjs +6 -6
- package/dist/{command-output-CBtzyIgF.mjs → command-output-Bt8ygHE7.mjs} +1 -1
- package/dist/{config-CgYMahz7.mjs → config-DC5jEtd1.mjs} +6 -2
- package/dist/{created-devices-DKbeWsiK.mjs → created-devices-D0s26Hx5.mjs} +2 -2
- package/dist/{dependency-state-xKoOypBm.mjs → dependency-state-DKaS1OM9.mjs} +2 -2
- package/dist/{detached-entry-BLfcgc4O.mjs → detached-entry-pB_IPfV4.mjs} +1 -1
- package/dist/{dev-client-CLnIH02x.mjs → dev-client-CDY_zAmD.mjs} +2 -2
- package/dist/{device-D7oCHGWi.mjs → device-BHw0WlHl.mjs} +8 -8
- package/dist/{device-capacity-EUOOYr8T.mjs → device-capacity-BoN1jQkO.mjs} +23 -12
- package/dist/device-host-worker.mjs +14 -14
- package/dist/{gradle-C6GKnunQ.mjs → device-ios-B2ruohE-.mjs} +659 -105
- package/dist/{device-lease-Co-EwifR.mjs → device-lease-Cu7PtQpZ.mjs} +5 -5
- package/dist/{device-lease-run-w1xhCqIW.mjs → device-lease-run-D38SnZtt.mjs} +4 -4
- package/dist/{device-pool-F5WvRPtD.mjs → device-pool-CP4rAsHx.mjs} +3 -3
- package/dist/{device-remote-tHbd1fKy.mjs → device-remote-B5GiUifk.mjs} +15 -16
- package/dist/{doctor-B9ckYUoU.mjs → doctor-PRJH94v6.mjs} +53 -29
- package/dist/doctor-watchman-wZhyTdp4.mjs +259 -0
- package/dist/{error-diagnostics-BRXOqDzG.mjs → error-diagnostics--v5HGOU0.mjs} +10 -10
- package/dist/{exec-DWhCZDGm.mjs → exec-i8GDPwq9.mjs} +32 -8
- package/dist/{gc-Dh6mXOKC.mjs → gc-CyHMcKcn.mjs} +19 -19
- package/dist/{guide-tm6igAaa.mjs → guide-dRaQJJk9.mjs} +409 -472
- package/dist/{hosted-android-Bv285t_t.mjs → hosted-android-Bs7fytj7.mjs} +3 -3
- package/dist/{hosted-client-C-rMtppF.mjs → hosted-client-C5G4h_OJ.mjs} +1 -1
- package/dist/{hosted-ios-D5mNmtj4.mjs → hosted-ios-Bik035eL.mjs} +1 -1
- package/dist/{hosted-logs-DN8Iz4mJ.mjs → hosted-logs-CI9Az9a4.mjs} +7 -7
- package/dist/{hosted-macos-B-wEjlwG.mjs → hosted-macos-DABm3ScO.mjs} +4 -4
- package/dist/{hosted-native-DeeOG8xZ.mjs → hosted-native-DbV2aUVw.mjs} +12 -8
- package/dist/{idle-shutdown-jjtxAn5C.mjs → idle-shutdown-DYiMBn34.mjs} +7 -7
- package/dist/{ios-B3SbOWdw.mjs → ios-BWbHFZVz.mjs} +5 -5
- package/dist/{ios-Bvbf0SGY.mjs → ios-DCrkgXEM.mjs} +1 -1
- package/dist/{ios-DNpdygiv.mjs → ios-DYUr9LGc.mjs} +7 -6
- package/dist/ios-ITYno9rO.mjs +2241 -0
- package/dist/{ios-device-vOaByMhw.mjs → ios-device-CJ_ZOGky.mjs} +3 -3
- package/dist/{ios-device-Bn7jWDB1.mjs → ios-device-CrW8aMb5.mjs} +1 -1
- package/dist/{ios-state-B2pES6Vs.mjs → ios-state-By0XuLTQ.mjs} +1 -1
- package/dist/{launch-verify-hskNcWkZ.mjs → launch-verify-DCveSE6d.mjs} +4 -4
- package/dist/{logs-1Ylc1Ri6.mjs → logs-Bao1HOMy.mjs} +10 -10
- package/dist/{macos-DF6C7wUU.mjs → macos-ciyBdTY5.mjs} +108 -130
- package/dist/macos-nIOATJmR.mjs +2 -0
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +7 -7
- package/dist/manifest-CX0d1IkZ.mjs +148 -0
- package/dist/{metro-Dh8T4Ytd.mjs → metro-DI2AjPF_.mjs} +194 -41
- package/dist/{metro-gateway-CEUw9RMH.mjs → metro-gateway-BxpJLIwh.mjs} +2 -2
- package/dist/{plan-placement-CtxkCO54.mjs → miss-reason-CjQCOKqq.mjs} +180 -296
- package/dist/{named-ports-BFIz1Shz.mjs → named-ports-B4iWH4E-.mjs} +12 -5
- package/dist/{native-runtime-D_603JiC.mjs → native-runtime-BGxsbfny.mjs} +6 -6
- package/dist/offload-worker.d.mts +1 -29
- package/dist/offload-worker.mjs +9 -8
- package/dist/{ownership-D6Se7gg_.mjs → ownership-EB0ySdGK.mjs} +2 -2
- package/dist/{placement-log-BcPhRwR4.mjs → placement-log-Dxe34rJm.mjs} +7 -3
- package/dist/plan-placement-BVY59qa8.mjs +290 -0
- package/dist/{ports-BLTtfBq-.mjs → ports-ByPc0_97.mjs} +3 -3
- package/dist/{prebuild-juCyreaR.mjs → prebuild-BKJ3wJI1.mjs} +4 -4
- package/dist/{preview-D5V07Nrl.mjs → preview-BbSottmO.mjs} +16 -17
- package/dist/project-B5eQ1USs.mjs +612 -0
- package/dist/{pull-request-u4vp7zmK.mjs → pull-request-IHNdMnG8.mjs} +1 -1
- package/dist/pull-requests.mjs +1 -1
- package/dist/react-native-ios-BMh2i25I.mjs +2 -0
- package/dist/react-native-ios-CSpIxexZ.mjs +2083 -0
- package/dist/{recordings-BAWltsVt.mjs → recordings-Bv8McZN4.mjs} +1 -1
- package/dist/{reload-DvyWzVjJ.mjs → reload-rAPdqeRR.mjs} +13 -14
- package/dist/{remote-cache-BGg7aGIZ.mjs → remote-cache-N3hAEaAL.mjs} +4 -4
- package/dist/{run-vhtDgpHO.mjs → run-lAkle1-c.mjs} +2 -2
- package/dist/{server-bare-B9E7S1aR.mjs → server-bare-CkIjnegq.mjs} +3 -3
- package/dist/server-expo-DGsdUGX2.mjs +2 -0
- package/dist/{server-expo-DoBHhuzK.mjs → server-expo-n3tUi3Em.mjs} +3 -3
- package/dist/{settings-Byp2AQ_E.mjs → settings-2am7TSxp.mjs} +5 -6
- package/dist/{settings-CQyMElEP.mjs → settings-CxgngUZk.mjs} +767 -15
- package/dist/settings.schema.json +72 -6
- package/dist/{simslim-EHBQ2R4G.mjs → simslim-D9LkJxIO.mjs} +5 -5
- package/dist/{slot-launch-C1nqh4mu.mjs → slot-launch-HV_KtPIw.mjs} +6 -6
- package/dist/{stage-g_WqWeaE.mjs → stage-BgaZJVZY.mjs} +1 -1
- package/dist/{start-NTc1Ifqs.mjs → start-D8NbxNBb.mjs} +1 -1
- package/dist/{start-D-IeOyoK.mjs → start-DtxthMfI.mjs} +29 -22
- package/dist/{state-BG-aAk4k.mjs → state-D2KtnALG.mjs} +2 -2
- package/dist/{state-xnqpx3AD.mjs → state-Tp4uImDS.mjs} +4 -2
- package/dist/{stats-DY6ekz8F.mjs → stats-8EJ5ivFT.mjs} +6 -6
- package/dist/{status-DCjZeE-K.mjs → status-BOyp0CUl.mjs} +25 -27
- package/dist/{stim-desktop-Behws_fi.mjs → stim-desktop-C65jk_q2.mjs} +1 -1
- package/dist/{stim-installations-aR_WsNOA.mjs → stim-installations-DbmUjsLv.mjs} +1 -1
- package/dist/stop-D0UIpZuh.mjs +72 -0
- package/dist/{stop-DIJtD2GL.mjs → stop-DRipAg-e.mjs} +2 -2
- package/dist/{stop-BTjs3xbc.mjs → stop-zDlknFoz.mjs} +78 -31
- package/dist/supervisor-run.mjs +14 -14
- package/dist/{support-BaayeYCf.mjs → support-CNqYkV0y.mjs} +7 -7
- package/dist/{support-Bwvbrq5-.mjs → support-DsNaFg6D.mjs} +5 -5
- package/dist/swiftpm-macos-aJzPAj1t.mjs +119 -0
- package/dist/{toolchain-Bnyd_K3A.mjs → toolchain-C3xSoyUl.mjs} +27 -270
- package/dist/{trigger-CJMhwXe8.mjs → trigger-CAhmG-4s.mjs} +3 -3
- package/dist/trigger-CoalsMTV.mjs +2 -0
- package/dist/{warm-progress-CjB-MP6H.mjs → warm-progress-pFLB2e6P.mjs} +133 -36
- package/dist/{status-Dcr0Qexd.mjs → watchman-BL1IdOtq.mjs} +75 -7
- package/dist/web-DFpFeZu5.mjs +2 -0
- package/dist/web-DbbrPUn0.mjs +127 -0
- package/dist/web-run.mjs +7 -7
- package/dist/{workspace-state-C59dqG-Z.mjs → workspace-state-CR9X86xJ.mjs} +1 -1
- package/dist/{workspaces-xXItD8Dj.mjs → workspaces-Djb2gfi9.mjs} +102 -18
- package/dist/{worktree-BSYlofkq.mjs → worktree-BL4M1rhB.mjs} +45 -42
- package/dist/{worktree-BJfnU6r5.mjs → worktree-DV-A0LNL.mjs} +1 -1
- package/package.json +5 -5
- package/shim/bundle-response.cjs +2 -1
- package/shim/bundle-response.d.cts +1 -1
- package/shim/expo-metro-config.cjs +1 -1
- package/dist/device-ios-6MewKKnc.mjs +0 -412
- package/dist/guide-status-Bhf9SJXc.mjs +0 -125
- package/dist/ios-CPdkoKaa.mjs +0 -3953
- package/dist/macos-Ck7OBMNY.mjs +0 -2
- package/dist/native-run-B06FkmZx.mjs +0 -158
- package/dist/project-C3ChRLZy.mjs +0 -212
- package/dist/projects-DD7dBTCj.mjs +0 -92
- package/dist/server-expo-Db9HBUoa.mjs +0 -2
- package/dist/stop-BGhKMOuH.mjs +0 -48
- package/dist/trigger-DWAq9hkw.mjs +0 -2
- package/dist/web-B6_bFDn7.mjs +0 -2
- package/dist/worktree-CsKYexJM.mjs +0 -753
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
import { n as ownership_claim_exports } from "./process-identity-Biv3arCO.mjs";
|
|
2
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
+
import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
|
|
3
3
|
import { t as spawnEntry } from "./spawn-entry-Dcb7sDUz.mjs";
|
|
4
4
|
import { r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
|
|
5
|
-
import { _ as stepTimer, c as launchErrorReport, f as refuseNoProject, g as stepClock, i as formatDuration, l as phaseLine, m as shortHash, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-
|
|
6
|
-
import { C as saveConfig, D as withConfigLock$1, E as upsertProject, L as deviceSlotFileKey, R as deviceSlotKey, V as parseDeviceSlotOption, W as validateDeviceSlot, _ as loadConfig$1, j as formatBytes, p as getProject, u as getConcurrencyLimits, w as setDevice, z as deviceSlotPlatforms } from "./config-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { l as
|
|
10
|
-
import {
|
|
11
|
-
import { F as recordFinishedBuild,
|
|
12
|
-
import {
|
|
13
|
-
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-
|
|
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, l as androidSystemImageAbi, q as resetAdoptedAvd, r as androidBuildToolName, rt as configuredAndroidEmulatorApp, t as DEFAULT_AVD_DEVICE_PROFILE, tt as waitForBoot, u as androidToolCwd } from "./android-
|
|
15
|
-
import { a as workspaceLinks, i as workspaceLinkLine } from "./stim-desktop-
|
|
16
|
-
import { A as publicUrlSetting, C as metroWarmupUrlSetting, F as resolveSettings, H as tunnelModeSetting, I as settingFile, K as detectProviders, M as remoteAndroidSetting, P as resolveCacheProviderConfig, Q as resolveOptimizations, R as settingOriginScope, T as parseIosRemote, U as unknownSettingKeys, V as settingsLayers, X as compilerCacheFallbackMessage, Y as artifactCachePolicy, Z as optimizationBuildProfile, i as SETTING_SHAPE_REMEDY, l as androidDataPartitionSizeGbSettingError, o as androidAvdConfigSettingError, u as cacheProviderSettingError, x as metroPortSetting, z as settingShapeErrors } from "./settings-CQyMElEP.mjs";
|
|
5
|
+
import { _ as stepTimer, c as launchErrorReport, f as refuseNoProject, g as stepClock, i as formatDuration, l as phaseLine, m as shortHash, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-Bt8ygHE7.mjs";
|
|
6
|
+
import { C as saveConfig, D as withConfigLock$1, E as upsertProject, L as deviceSlotFileKey, R as deviceSlotKey, V as parseDeviceSlotOption, W as validateDeviceSlot, _ as loadConfig$1, j as formatBytes, p as getProject, u as getConcurrencyLimits, w as setDevice, z as deviceSlotPlatforms } from "./config-DC5jEtd1.mjs";
|
|
7
|
+
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-CR9X86xJ.mjs";
|
|
8
|
+
import { M as writeWorkspaceLaunch, b as MODE_EXPO, c as projectShortcut, p as detectIsExpo, r as findProjectRoot, s as projectProblem, t as NO_PROJECT_REFUSAL, y as MODE_BARE } from "./project-B5eQ1USs.mjs";
|
|
9
|
+
import { A as publicUrlSetting, B as settingShapeErrors, C as metroWarmupUrlSetting, Ct as removeTemporaryEntry, Dt as optimizationBuildProfile, Et as compilerCacheFallbackMessage, F as resolveCacheProviderConfig, H as settingsLayers, I as resolveSettings, L as settingFile, M as remoteAndroidSetting, N as remoteEasFallbackSetting, Ot as resolveOptimizations, St as makeTemporaryDirectory, T as parseIosRemote, Tt as artifactCachePolicy, U as tunnelModeSetting, W as unknownSettingKeys, i as SETTING_SHAPE_REMEDY, l as androidDataPartitionSizeGbSettingError, mt as repoRoot, nt as gitCommonDir, o as androidAvdConfigSettingError, q as detectProviders, u as cacheProviderSettingError, x as metroPortSetting, z as settingOriginScope } from "./settings-CxgngUZk.mjs";
|
|
10
|
+
import { d as signalProcessTree, s as pidExists, u as resolveProjectMetro } from "./metro-DI2AjPF_.mjs";
|
|
11
|
+
import { F as recordFinishedBuild, I as startBuildProgress, L as tapBuildLog, O as NO_BUILD_PROGRESS, R as createRunRecorder, U as recordRunStats, V as recordCapacityRefusal, W as statsProjectKey$1, t as budgetGate, z as readRunEstimates } from "./budget-Dz-kyXLv.mjs";
|
|
12
|
+
import { D as teardownOwnedAvd, M as acquireBuildSlot, P as releaseBuildSlot } from "./workspaces-Djb2gfi9.mjs";
|
|
13
|
+
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-Cu7PtQpZ.mjs";
|
|
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, l as androidSystemImageAbi, q as resetAdoptedAvd, r as androidBuildToolName, rt as configuredAndroidEmulatorApp, t as DEFAULT_AVD_DEVICE_PROFILE, tt as waitForBoot, u as androidToolCwd } from "./android-BdQC6zs1.mjs";
|
|
15
|
+
import { a as workspaceLinks, i as workspaceLinkLine } from "./stim-desktop-C65jk_q2.mjs";
|
|
17
16
|
import { r as createNdjsonWriter } from "./ndjson-LGZAMsqa.mjs";
|
|
18
|
-
import {
|
|
19
|
-
import { n as DeviceAdmissionRefusal, r as checkDeviceCapacity, t as DEFAULT_DEVICE_SLOT_WAIT_MS } from "./device-capacity-
|
|
20
|
-
import {
|
|
21
|
-
import { t as
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import { n as
|
|
26
|
-
import { n as
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import { a as
|
|
31
|
-
import {
|
|
32
|
-
import { a as
|
|
33
|
-
import { d as
|
|
34
|
-
import { a as
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import { t as
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import { a as
|
|
43
|
-
import {
|
|
17
|
+
import { A as resolveBuildPlacement, C as setRemoteLogSink, D as parseBuildMachineOption, E as namedBuildMachine, O as requireLocalBuild, S as withNativeBuildRun, a as offloadBuild, b as runCancellation, c as placementLoad, i as closeOffload, l as remotePhaseText, n as buildPlacementCandidates, p as cancelledFailure, r as chooseBuildMachine, s as offloadPlacement, w as OffloadRefusal, x as runCancellationSignal } from "./client-CuUo8Nvg.mjs";
|
|
18
|
+
import { n as DeviceAdmissionRefusal, r as checkDeviceCapacity, t as DEFAULT_DEVICE_SLOT_WAIT_MS } from "./device-capacity-BoN1jQkO.mjs";
|
|
19
|
+
import { i as ccacheActivityLine, n as CCACHE_NOT_RUN, r as CCACHE_UNAVAILABLE, s as resolveCcache } from "./manifest-CX0d1IkZ.mjs";
|
|
20
|
+
import { E as startBuildHeartbeat, O as tailLines, h as HEARTBEAT_INTERVAL_MS, n as androidToolchain, t as androidRequirements } from "./toolchain-C3xSoyUl.mjs";
|
|
21
|
+
import { t as cleanLine } from "./server-expo-n3tUi3Em.mjs";
|
|
22
|
+
import { r as hostedMetroSettings } from "./metro-gateway-BxpJLIwh.mjs";
|
|
23
|
+
import { a as writeHostedAndroid, i as writeDevicePlacement, t as readHostedAndroid } from "./ios-state-By0XuLTQ.mjs";
|
|
24
|
+
import { _ as devicePlacementLine, a as UPDATES_MANIFEST_NAME, d as ensureOwnedDevice, f as AvdBootError, g as automaticDevicePlacement, h as checkEasFallback, i as skippedMissReason, l as didSetUpDevice, m as warmMetro, n as fingerprintErrorMissReason, o as detectEntryFile, p as AvdRecoveryError, s as refreshUpdatesManifestFile, t as explainBuildMiss, u as ensureBooted } from "./miss-reason-CjQCOKqq.mjs";
|
|
25
|
+
import { n as devicePlacementRecord, t as buildPlacementRecord } from "./placement-log-Dxe34rJm.mjs";
|
|
26
|
+
import { n as prepareHostedAndroid, t as placeHostedAndroid } from "./hosted-android-Bs7fytj7.mjs";
|
|
27
|
+
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-CFI4ptUL.mjs";
|
|
28
|
+
import { n as nativeRunCommand, r as siblingPlatformSlots, t as launchSlotScope } from "./slot-launch-HV_KtPIw.mjs";
|
|
29
|
+
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-DCveSE6d.mjs";
|
|
30
|
+
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-N3hAEaAL.mjs";
|
|
31
|
+
import { C as resolveSystemImage, S as resolveDeviceProfile, T as systemImageRefusal, _ as isReleaseVariant, a as PLATFORM, b as pooledAndroidDevice, d as apkPackage, f as deviceProfileRefusal, g as foldableImageRefusal, i as NO_FINGERPRINT, m as dumpApkManifest, n as LAUNCH_FAILED, o as androidBuildOptions, p as displayPath, r as NO_DEVICE, s as androidDevClientScheme, t as INSTALL_FAILED, v as noDeviceDiagnostic, w as resolveVariant, x as remoteAvdFlagRefusal } from "./support-DsNaFg6D.mjs";
|
|
32
|
+
import { d as productFlavorRefusal, f as readProductFlavors, h as formatDiagnostic, o as buildAndroid } from "./device-ios-B2ruohE-.mjs";
|
|
33
|
+
import { T as ownedSessionName, a as ensureMetroReachable, c as remoteAndroidDeps, n as binOnPath, o as ensureRemoteBootOwned, u as resolveRemoteContext } from "./device-remote-B5GiUifk.mjs";
|
|
34
|
+
import { a as isEasBuildFailure, o as planEasDevelopmentBuild, s as resolveEasDevelopmentBuild } from "./simslim-D9LkJxIO.mjs";
|
|
35
|
+
import { c as startDevServer, m as detectAppIds, p as detectAndroidPackage } from "./start-DtxthMfI.mjs";
|
|
36
|
+
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-D38SnZtt.mjs";
|
|
37
|
+
import { n as verifyCollectorOwnership, r as readCollectors } from "./ownership-EB0ySdGK.mjs";
|
|
38
|
+
import { i as launchOutcomeRecord, n as ensureWorkspaceStorageSafely, r as isPhysicalDeviceRequest, t as ensureDevServer } from "./native-runtime-BGxsbfny.mjs";
|
|
39
|
+
import { t as selectFromPool } from "./device-pool-CP4rAsHx.mjs";
|
|
40
|
+
import { i as staleNativeDirRefusal, n as recordPrebuild, r as runPrebuild, t as planPrebuild } from "./prebuild-BKJ3wJI1.mjs";
|
|
41
|
+
import { a as printPlan, i as planPayload, n as planCachedBuild, o as refusePlan, r as planFlagRefusal, s as runArtifactLifecycle, t as planHostedDevice } from "./plan-placement-BVY59qa8.mjs";
|
|
42
|
+
import { a as printNativeCrashReport, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics--v5HGOU0.mjs";
|
|
43
|
+
import { n as resolveAndroidCas, r as resolveAndroidCompilerCache } from "./android-cas-C87geAg-.mjs";
|
|
44
44
|
import { constants, copyFileSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync } from "node:fs";
|
|
45
45
|
import { basename, dirname, isAbsolute, join } from "node:path";
|
|
46
46
|
import { buildDiagnostics, hostedAndroidStatus, machineCapacity, parseMachine } from "@stim-cli/core/state";
|
|
@@ -92,7 +92,7 @@ async function connectAndroidHosting({ root, slot, machine, release, metroCheck,
|
|
|
92
92
|
} };
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
async function selectAndroidPlacement({ target: selected, automatic = automaticDevicePlacement, checkBudget = budgetGate, note, phase, log, fromFlag, noWait, buildMachine, localSelectors, ...args }) {
|
|
95
|
+
async function selectAndroidPlacement({ target: selected, automatic = automaticDevicePlacement, checkBudget = budgetGate, note, phase, log, fromFlag, noWait, buildMachine, localSelectors, eas, ...args }) {
|
|
96
96
|
const selectors = selected.kind === "hosted" ? {
|
|
97
97
|
...selected.systemImage ? { systemImage: selected.systemImage } : {},
|
|
98
98
|
...selected.deviceProfile ? { deviceProfile: selected.deviceProfile } : {}
|
|
@@ -126,14 +126,31 @@ async function selectAndroidPlacement({ target: selected, automatic = automaticD
|
|
|
126
126
|
platform: "android",
|
|
127
127
|
selectors,
|
|
128
128
|
buildMachine,
|
|
129
|
-
noWait
|
|
129
|
+
noWait,
|
|
130
|
+
...eas ? { eas } : {}
|
|
130
131
|
});
|
|
131
132
|
phase("placement:", devicePlacementLine(placed.placement, placed.skipped));
|
|
132
133
|
log?.(devicePlacementRecord({
|
|
133
134
|
platform: "android",
|
|
134
135
|
fromFlag,
|
|
136
|
+
easFallback: Boolean(eas),
|
|
135
137
|
placed
|
|
136
138
|
}));
|
|
139
|
+
if (placed.placement.decision === "eas") return {
|
|
140
|
+
target: {
|
|
141
|
+
kind: "remote",
|
|
142
|
+
backend: "eas",
|
|
143
|
+
systemImage: selected.systemImage,
|
|
144
|
+
deviceProfile: selected.deviceProfile
|
|
145
|
+
},
|
|
146
|
+
hostedTarget: null,
|
|
147
|
+
selectors,
|
|
148
|
+
budget: await checkBudget({
|
|
149
|
+
root: args.root,
|
|
150
|
+
note
|
|
151
|
+
}),
|
|
152
|
+
devicePlacement: placed.placement
|
|
153
|
+
};
|
|
137
154
|
if (placed.target && !args.release && !args.metroCheck) return { failure: {
|
|
138
155
|
code: "STIM_BAD_ARG",
|
|
139
156
|
message: "Hosted Debug runs require the local Metro supervisor; --no-metro-check cannot be used.",
|
|
@@ -344,7 +361,7 @@ function persistLastBuild({ recordBuild = recordFinishedBuild, root, record, sta
|
|
|
344
361
|
}
|
|
345
362
|
//#endregion
|
|
346
363
|
//#region src/commands/android/hosted.ts
|
|
347
|
-
async function finishHostedAndroidRun({ target, artifact, root, slot = "default", release, isExpo, metroPort, logsDir, selectors, place, writePlacement, verifyLaunch: verify, writeLaunch, readApkPackage, resolveDevClientScheme, now, started, startedAt, fail, phase, out, recordBuild, ...report }) {
|
|
364
|
+
async function finishHostedAndroidRun({ target, artifact, root, slot = "default", release, isExpo, metroPort, logsDir, selectors, place, writePlacement, verifyLaunch: verify, writeLaunch, readApkPackage, resolveDevClientScheme, now, started, startedAt, fail, phase, enterPhase, out, recordBuild, ...report }) {
|
|
348
365
|
const packageName = artifact.androidPackage ?? readApkPackage(artifact.apkPath);
|
|
349
366
|
if (!artifact.apkPath || !packageName) return fail("STIM_INSTALL_FAILED", "The built APK has no package identity.");
|
|
350
367
|
const launchedAt = now();
|
|
@@ -360,7 +377,8 @@ async function finishHostedAndroidRun({ target, artifact, root, slot = "default"
|
|
|
360
377
|
selectors,
|
|
361
378
|
...!release && isExpo ? { devClientScheme: resolveDevClientScheme(root, artifact.apkPath) ?? void 0 } : {},
|
|
362
379
|
reserved: (placement) => writePlacement(root, slot, placement),
|
|
363
|
-
note: out
|
|
380
|
+
note: out,
|
|
381
|
+
enterPhase
|
|
364
382
|
});
|
|
365
383
|
writePlacement(root, slot, run.placement);
|
|
366
384
|
writeLaunch(root, "android", {
|
|
@@ -807,6 +825,13 @@ function fail$1(code, message, remedy, extra = {}) {
|
|
|
807
825
|
extra
|
|
808
826
|
};
|
|
809
827
|
}
|
|
828
|
+
var ArtifactRefusal = class extends Error {
|
|
829
|
+
failure;
|
|
830
|
+
constructor(failure) {
|
|
831
|
+
super(failure.message ?? failure.code);
|
|
832
|
+
this.failure = failure;
|
|
833
|
+
}
|
|
834
|
+
};
|
|
810
835
|
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 }) {
|
|
811
836
|
const { phase, out, estimates, stats, step, miss, hit: lateHit, place, waitingOn, waitingFor } = progress;
|
|
812
837
|
let fallbackMachine = null;
|
|
@@ -826,6 +851,7 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
826
851
|
}
|
|
827
852
|
}));
|
|
828
853
|
if (namedBuildMachine(buildMachine)) throw new OffloadRefusal(buildMachine, reason);
|
|
854
|
+
requireLocalBuild(buildMachine);
|
|
829
855
|
record.offloadFallback = reason;
|
|
830
856
|
phase("build", `${line} -> building here`);
|
|
831
857
|
};
|
|
@@ -834,11 +860,6 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
834
860
|
let androidPackage = initialPackage;
|
|
835
861
|
let ccacheActivity = CCACHE_NOT_RUN;
|
|
836
862
|
let phaseFailure = null;
|
|
837
|
-
const refused = () => ({
|
|
838
|
-
ok: false,
|
|
839
|
-
failure: phaseFailure,
|
|
840
|
-
ccache: ccacheActivity
|
|
841
|
-
});
|
|
842
863
|
let buildLock = null;
|
|
843
864
|
const releaseHeldLock = () => {
|
|
844
865
|
if (!buildLock) return;
|
|
@@ -957,7 +978,6 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
957
978
|
apkPath = found?.path ?? null;
|
|
958
979
|
return true;
|
|
959
980
|
}
|
|
960
|
-
if (!await resolveInitialFingerprint()) return refused();
|
|
961
981
|
let remote = null;
|
|
962
982
|
let abandonedRemote = false;
|
|
963
983
|
let uploadPending = null;
|
|
@@ -1009,13 +1029,9 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
1009
1029
|
} else phase("cache", `remote miss (${remote.name}) ${remoteTimer()}`);
|
|
1010
1030
|
}
|
|
1011
1031
|
}
|
|
1012
|
-
if (!easBuild) {
|
|
1013
|
-
await resolveRemoteArtifact();
|
|
1014
|
-
if (!apkPath) miss(reasonForMiss([]).reason);
|
|
1015
|
-
}
|
|
1016
1032
|
let waitedForBuild = null;
|
|
1017
1033
|
let releasedWait = null;
|
|
1018
|
-
|
|
1034
|
+
async function awaitSharedBuild() {
|
|
1019
1035
|
const shared = await waitForSharedBuild({
|
|
1020
1036
|
platform: PLATFORM,
|
|
1021
1037
|
key: cacheKey,
|
|
@@ -1037,7 +1053,7 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
1037
1053
|
if (shared.refusal) {
|
|
1038
1054
|
const { code, message, remedy } = shared.refusal;
|
|
1039
1055
|
phaseFailure = fail$1(code, message, remedy, { lastBuildStatus: true });
|
|
1040
|
-
|
|
1056
|
+
throw new ArtifactRefusal(phaseFailure);
|
|
1041
1057
|
}
|
|
1042
1058
|
buildLock = shared.lock;
|
|
1043
1059
|
releasedWait = shared.released;
|
|
@@ -1046,6 +1062,7 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
1046
1062
|
record.cacheHit = "local";
|
|
1047
1063
|
waitedForBuild = shared.hit.waited;
|
|
1048
1064
|
}
|
|
1065
|
+
return apkPath;
|
|
1049
1066
|
}
|
|
1050
1067
|
let swapDir = null;
|
|
1051
1068
|
const installableCachedApk = async (key, cachedPath) => {
|
|
@@ -1071,15 +1088,13 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
1071
1088
|
swapFellBack = true;
|
|
1072
1089
|
return null;
|
|
1073
1090
|
};
|
|
1074
|
-
async function prepareCachedArtifact() {
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
record.cacheHit = false;
|
|
1080
|
-
waitedForBuild = null;
|
|
1081
|
-
}
|
|
1091
|
+
async function prepareCachedArtifact(cachedPath) {
|
|
1092
|
+
const prepared = await installableCachedApk(cacheKey, cachedPath);
|
|
1093
|
+
if (!prepared) {
|
|
1094
|
+
record.cacheHit = false;
|
|
1095
|
+
waitedForBuild = null;
|
|
1082
1096
|
}
|
|
1097
|
+
return prepared;
|
|
1083
1098
|
}
|
|
1084
1099
|
function reasonForMiss(rekeyedBy) {
|
|
1085
1100
|
if (swapFellBack) return {
|
|
@@ -1122,9 +1137,11 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
1122
1137
|
}
|
|
1123
1138
|
}
|
|
1124
1139
|
async function takeBuildSlot() {
|
|
1140
|
+
requireLocalBuild(buildMachine);
|
|
1125
1141
|
if (!maxBuilds) return true;
|
|
1126
1142
|
try {
|
|
1127
1143
|
buildSlot = await acquireSlot({
|
|
1144
|
+
automatic: buildMachine === "auto",
|
|
1128
1145
|
max: maxBuilds,
|
|
1129
1146
|
root,
|
|
1130
1147
|
logFile: buildLog,
|
|
@@ -1133,6 +1150,7 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
1133
1150
|
});
|
|
1134
1151
|
slotWaitMs = buildSlot.slotWaitMs;
|
|
1135
1152
|
} catch (err) {
|
|
1153
|
+
requireLocalBuild(buildMachine);
|
|
1136
1154
|
const refusal = (0, ownership_claim_exports.claimFailure)(err, "stim android");
|
|
1137
1155
|
if (refusal) {
|
|
1138
1156
|
phaseFailure = fail$1(refusal.code, refusal.message, refusal.remedy, { lastBuildStatus: true });
|
|
@@ -1144,12 +1162,13 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
1144
1162
|
}
|
|
1145
1163
|
/** Whether this build should leave this Mac, before any machine is asked; null builds here. */
|
|
1146
1164
|
function placeBuild() {
|
|
1147
|
-
const { mode, machines } = buildPlacementCandidates(buildMachine);
|
|
1148
|
-
if (machines.length === 0 && !namedBuildMachine(buildMachine) && buildMachine !== "local") return null;
|
|
1165
|
+
const { mode, machines, localEnabled } = buildPlacementCandidates(buildMachine);
|
|
1166
|
+
if (localEnabled && machines.length === 0 && !namedBuildMachine(buildMachine) && buildMachine !== "local") return null;
|
|
1149
1167
|
const unsupported = physical ? "device builds build here" : remoteTarget ? "remote device builds build here" : release ? `${variant} builds build here` : cas ? "Apple Clang CAS builds build here" : !cachePolicy.write ? "the build cache is off" : null;
|
|
1150
1168
|
const here = machineCapacity();
|
|
1151
1169
|
const placement = offloadPlacement({
|
|
1152
1170
|
mode,
|
|
1171
|
+
localEnabled,
|
|
1153
1172
|
machines: machines.length,
|
|
1154
1173
|
here,
|
|
1155
1174
|
unsupported,
|
|
@@ -1330,228 +1349,284 @@ async function acquireAndroidArtifact({ root, buildLog, writer, settings, isExpo
|
|
|
1330
1349
|
});
|
|
1331
1350
|
return true;
|
|
1332
1351
|
}
|
|
1333
|
-
async function
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1352
|
+
async function prepareSource() {
|
|
1353
|
+
const rekeyedBy = [];
|
|
1354
|
+
const prebuildPlan = planPrebuildFor(root, PLATFORM, {
|
|
1355
|
+
isExpo,
|
|
1356
|
+
fingerprint: hash,
|
|
1357
|
+
sources: fingerprintSources
|
|
1358
|
+
});
|
|
1359
|
+
const prebuildRan = prebuildPlan === "generate" || prebuildPlan === "regenerate";
|
|
1360
|
+
if (prebuildPlan === "refuse") {
|
|
1361
|
+
const refusal = staleNativeDirRefusal(PLATFORM);
|
|
1362
|
+
phaseFailure = fail$1(refusal.code, refusal.message, refusal.remedy, { lastBuildStatus: true });
|
|
1363
|
+
throw new ArtifactRefusal(phaseFailure);
|
|
1364
|
+
}
|
|
1365
|
+
if (prebuildRan) {
|
|
1366
|
+
miss(reasonForMiss([]).reason, true);
|
|
1367
|
+
step("prebuild");
|
|
1368
|
+
recordPrebuild(root, PLATFORM, null);
|
|
1369
|
+
const pre = await prebuild(root, PLATFORM, writer, {
|
|
1340
1370
|
isExpo,
|
|
1341
|
-
|
|
1342
|
-
sources: fingerprintSources
|
|
1371
|
+
clean: prebuildPlan === "regenerate"
|
|
1343
1372
|
});
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
}
|
|
1350
|
-
if (prebuildRan) {
|
|
1351
|
-
miss(reasonForMiss([]).reason, true);
|
|
1352
|
-
step("prebuild");
|
|
1353
|
-
recordPrebuild(root, PLATFORM, null);
|
|
1354
|
-
const pre = await prebuild(root, PLATFORM, writer, {
|
|
1355
|
-
isExpo,
|
|
1356
|
-
clean: prebuildPlan === "regenerate"
|
|
1357
|
-
});
|
|
1358
|
-
if (pre.failed) {
|
|
1359
|
-
phaseFailure = fail$1(pre.code, pre.reason, pre.remedy, {
|
|
1360
|
-
lastBuildStatus: true,
|
|
1361
|
-
lines: tail(pre.lastLines),
|
|
1362
|
-
logPath: displayPath(root, buildLog)
|
|
1363
|
-
});
|
|
1364
|
-
return false;
|
|
1365
|
-
}
|
|
1366
|
-
phase("prebuild", `${prebuildPlan === "generate" ? "android/ generated" : "android/ not generated from this fingerprint -> regenerated with --clean"} (${formatDuration(pre.durationMs)})`);
|
|
1367
|
-
androidPackage = detectAndroidPackage(root) || androidPackage;
|
|
1368
|
-
record.bundleId = androidPackage;
|
|
1369
|
-
const after = await refingerprintAfterMutation({
|
|
1370
|
-
projectRoot: root,
|
|
1371
|
-
platform: PLATFORM,
|
|
1372
|
-
previousHash: hash,
|
|
1373
|
-
fingerprint
|
|
1373
|
+
if (pre.failed) {
|
|
1374
|
+
phaseFailure = fail$1(pre.code, pre.reason, pre.remedy, {
|
|
1375
|
+
lastBuildStatus: true,
|
|
1376
|
+
lines: tail(pre.lastLines),
|
|
1377
|
+
logPath: displayPath(root, buildLog)
|
|
1374
1378
|
});
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1379
|
+
throw new ArtifactRefusal(phaseFailure);
|
|
1380
|
+
}
|
|
1381
|
+
phase("prebuild", `${prebuildPlan === "generate" ? "android/ generated" : "android/ not generated from this fingerprint -> regenerated with --clean"} (${formatDuration(pre.durationMs)})`);
|
|
1382
|
+
androidPackage = detectAndroidPackage(root) || androidPackage;
|
|
1383
|
+
record.bundleId = androidPackage;
|
|
1384
|
+
}
|
|
1385
|
+
return {
|
|
1386
|
+
prebuildRan,
|
|
1387
|
+
rekeyedBy,
|
|
1388
|
+
editedConfig: []
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
async function revalidateSource(preparation) {
|
|
1392
|
+
const { prebuildRan, rekeyedBy } = preparation;
|
|
1393
|
+
if (prebuildRan) {
|
|
1394
|
+
const after = await refingerprintAfterMutation({
|
|
1395
|
+
projectRoot: root,
|
|
1396
|
+
platform: PLATFORM,
|
|
1397
|
+
previousHash: hash,
|
|
1398
|
+
fingerprint
|
|
1399
|
+
});
|
|
1400
|
+
preparation.editedConfig = after ? configInputsChanged(fingerprintSources, after.sources, { prebuildRan }) : [];
|
|
1401
|
+
const { editedConfig } = preparation;
|
|
1402
|
+
if (after && !editedConfig.length) recordPrebuild(root, PLATFORM, after.hash);
|
|
1403
|
+
if (after?.moved && !editedConfig.length) {
|
|
1404
|
+
rekeyedBy.push("prebuild");
|
|
1405
|
+
storeHash = after.hash;
|
|
1406
|
+
storeSources = after.sources;
|
|
1407
|
+
storeKey = buildCacheKey(PLATFORM, after.hash, buildRunOptions);
|
|
1408
|
+
record.fingerprint = storeHash;
|
|
1409
|
+
record.cacheKey = storeKey;
|
|
1410
|
+
phase("fingerprint", chalk.dim(`${shortHash(hash)} -> ${shortHash(storeHash)} (after prebuild)`));
|
|
1411
|
+
const late = useBuildCache ? resolveCached(PLATFORM, storeKey) : null;
|
|
1412
|
+
if (late) {
|
|
1413
|
+
const prepared = await installableCachedApk(storeKey, late);
|
|
1414
|
+
if (prepared) {
|
|
1415
|
+
apkPath = prepared;
|
|
1416
|
+
record.cacheHit = "local";
|
|
1417
|
+
lateHit();
|
|
1418
|
+
phase("cache", `hit ${shortHash(storeHash)} (post-prebuild key)`);
|
|
1419
|
+
if (releasedWait) {
|
|
1420
|
+
waitedForBuild = releasedWait.facts;
|
|
1421
|
+
phase("build", `waited ${formatDuration(waitedForBuild.ms)} for ${releasedWait.who}'s build -> installed from cache -- stim guide lifecycle concurrency`);
|
|
1397
1422
|
}
|
|
1398
1423
|
}
|
|
1399
1424
|
}
|
|
1400
1425
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
} catch (err) {
|
|
1524
|
-
phase("cache", chalk.yellow(`could not store the build: ${err?.message || err}`));
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
if (remote) uploadPending = uploadRemoteBuild({
|
|
1528
|
-
logWriter: writer,
|
|
1529
|
-
provider: remote.provider,
|
|
1530
|
-
platform: PLATFORM,
|
|
1426
|
+
}
|
|
1427
|
+
return apkPath ? { ready: apkPath } : null;
|
|
1428
|
+
}
|
|
1429
|
+
async function acquireRemoteArtifact(offload, { rekeyedBy, editedConfig }) {
|
|
1430
|
+
explainMiss(rekeyedBy);
|
|
1431
|
+
step("compile");
|
|
1432
|
+
if (editedConfig.length) fallBack("prebuild changed config inputs, so the APK cannot be cached", "offload failed: prebuild changed config inputs, so the APK cannot be cached");
|
|
1433
|
+
else {
|
|
1434
|
+
const choice = await chooseMachine(offload);
|
|
1435
|
+
if (choice) await compileElsewhere(choice, offload);
|
|
1436
|
+
}
|
|
1437
|
+
return apkPath ? { ready: apkPath } : null;
|
|
1438
|
+
}
|
|
1439
|
+
async function compileHere(offload, { rekeyedBy }) {
|
|
1440
|
+
if (!offload) {
|
|
1441
|
+
explainMiss(rekeyedBy);
|
|
1442
|
+
step("compile");
|
|
1443
|
+
}
|
|
1444
|
+
if (offload) stats.setPlacement({
|
|
1445
|
+
decision: "fell-back",
|
|
1446
|
+
slotWaitMs,
|
|
1447
|
+
deviceSlotWaitMs: stats.deviceSlotWaitMs(),
|
|
1448
|
+
reason: record.offloadFallback ?? "offload failed",
|
|
1449
|
+
...fallbackMachine ? { machine: fallbackMachine } : {}
|
|
1450
|
+
});
|
|
1451
|
+
else stats.setPlacement({
|
|
1452
|
+
decision: "here",
|
|
1453
|
+
reason: hereReason,
|
|
1454
|
+
slotWaitMs,
|
|
1455
|
+
deviceSlotWaitMs: stats.deviceSlotWaitMs()
|
|
1456
|
+
});
|
|
1457
|
+
requireLocalBuild(buildMachine);
|
|
1458
|
+
record.builtOn = "here";
|
|
1459
|
+
phase("build", `compiling ${variant || "debug"} with Gradle`);
|
|
1460
|
+
const built = await build({
|
|
1461
|
+
root,
|
|
1462
|
+
logWriter: writer,
|
|
1463
|
+
variant,
|
|
1464
|
+
abi: buildAbi
|
|
1465
|
+
}, {
|
|
1466
|
+
estimateMs: estimates().coldBuildMs,
|
|
1467
|
+
ccache: buildPlan.compilerCache === "ccache" ? ccacheFor({
|
|
1468
|
+
root,
|
|
1469
|
+
onNote: out
|
|
1470
|
+
}) : null,
|
|
1471
|
+
cas,
|
|
1472
|
+
buildCache: buildPlan.gradleBuildCache,
|
|
1473
|
+
pch: buildPlan.pch,
|
|
1474
|
+
compilerCacheDisabled: buildPlan.compilerCache === "none"
|
|
1475
|
+
});
|
|
1476
|
+
ccacheActivity = built.ccache ?? CCACHE_UNAVAILABLE;
|
|
1477
|
+
phase("cache", `compilation cache ${ccacheActivityLine(ccacheActivity)}`);
|
|
1478
|
+
if (!built.ok) {
|
|
1479
|
+
const diagnostics = built.diagnostics;
|
|
1480
|
+
for (const diag of diagnostics) writer.write({
|
|
1481
|
+
src: "build",
|
|
1482
|
+
level: "error",
|
|
1483
|
+
event: "gradle_diagnostic",
|
|
1484
|
+
msg: formatDiagnostic(diag)
|
|
1485
|
+
});
|
|
1486
|
+
phase("build", chalk.red(`FAILED after ${formatDuration(built.durationMs)}`));
|
|
1487
|
+
const extracted = diagnostics.map(formatDiagnostic);
|
|
1488
|
+
if (built.truncated > 0) extracted.push(`... and ${built.truncated} more diagnostic(s) in the log`);
|
|
1489
|
+
phaseFailure = fail$1(built.code, built.reason, diagnostics.find((d) => d.remedy)?.remedy || built.remedy || null, {
|
|
1490
|
+
lastBuildStatus: true,
|
|
1491
|
+
diagnostics: extracted,
|
|
1492
|
+
buildDiagnostics: diagnostics,
|
|
1493
|
+
lines: extracted.length ? [] : tail(built.lastLines),
|
|
1494
|
+
logPath: displayPath(root, buildLog)
|
|
1495
|
+
});
|
|
1496
|
+
throw new ArtifactRefusal(phaseFailure);
|
|
1497
|
+
}
|
|
1498
|
+
apkPath = built.apkPath;
|
|
1499
|
+
stats.setBuildMs(built.durationMs);
|
|
1500
|
+
phase("build", `ok (${formatDuration(built.durationMs)})`);
|
|
1501
|
+
if (built.apkNote) phase("build", chalk.yellow(built.apkNote));
|
|
1502
|
+
return apkPath;
|
|
1503
|
+
}
|
|
1504
|
+
async function validateCompiled({ prebuildRan, editedConfig }) {
|
|
1505
|
+
const beforeBuildHash = storeHash;
|
|
1506
|
+
const afterBuild = editedConfig.length ? null : await refingerprintAfterMutation({
|
|
1507
|
+
projectRoot: root,
|
|
1508
|
+
platform: PLATFORM,
|
|
1509
|
+
previousHash: beforeBuildHash,
|
|
1510
|
+
fingerprint
|
|
1511
|
+
});
|
|
1512
|
+
const changedDuringBuild = afterBuild ? inputsChangedDuringBuild({
|
|
1513
|
+
platform: PLATFORM,
|
|
1514
|
+
lookup: fingerprintSources,
|
|
1515
|
+
prebuildRan,
|
|
1516
|
+
compiled: storeSources,
|
|
1517
|
+
current: afterBuild.sources
|
|
1518
|
+
}) : editedConfig;
|
|
1519
|
+
if (!afterBuild || changedDuringBuild.length) {
|
|
1520
|
+
record.fingerprint = null;
|
|
1521
|
+
record.cacheKey = null;
|
|
1522
|
+
phase("fingerprint", chalk.yellow(changedDuringBuild.length ? changedDuringBuildLine(changedDuringBuild) : "unavailable after Gradle; the build will be installed but not cached"));
|
|
1523
|
+
return "uncacheable";
|
|
1524
|
+
}
|
|
1525
|
+
if (afterBuild.moved) {
|
|
1526
|
+
storeHash = afterBuild.hash;
|
|
1527
|
+
storeSources = afterBuild.sources;
|
|
1528
|
+
storeKey = buildCacheKey(PLATFORM, afterBuild.hash, buildRunOptions);
|
|
1529
|
+
record.fingerprint = storeHash;
|
|
1530
|
+
record.cacheKey = storeKey;
|
|
1531
|
+
phase("fingerprint", chalk.dim(`${shortHash(beforeBuildHash)} -> ${shortHash(storeHash)} (after Gradle)`));
|
|
1532
|
+
}
|
|
1533
|
+
return "cacheable";
|
|
1534
|
+
}
|
|
1535
|
+
async function storeArtifact(artifactPath) {
|
|
1536
|
+
if (cachePolicy.write) {
|
|
1537
|
+
const assetManifest = release ? captureAssets(root, { variant }) : null;
|
|
1538
|
+
try {
|
|
1539
|
+
const stored = await storeTieredBuild({
|
|
1540
|
+
local: filesystemBuildCapability({
|
|
1541
|
+
resolve: resolveCached,
|
|
1542
|
+
store: storeCached,
|
|
1543
|
+
sources: storeSources,
|
|
1544
|
+
assetManifest
|
|
1545
|
+
}),
|
|
1546
|
+
loadProvider: loadTieredProvider,
|
|
1547
|
+
target: {
|
|
1531
1548
|
projectRoot: root,
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1549
|
+
platform: PLATFORM,
|
|
1550
|
+
key: storeKey
|
|
1551
|
+
},
|
|
1552
|
+
sourcePath: artifactPath,
|
|
1553
|
+
overwrite: !useBuildCache || swapFellBack,
|
|
1554
|
+
warn: cacheWarn
|
|
1555
|
+
});
|
|
1556
|
+
providerUpload = stored.providerUpload;
|
|
1557
|
+
providerName = stored.providerName ?? providerName;
|
|
1558
|
+
} catch (err) {
|
|
1559
|
+
phase("cache", chalk.yellow(`could not store the build: ${err?.message || err}`));
|
|
1537
1560
|
}
|
|
1538
|
-
} catch (error) {
|
|
1539
|
-
if (!(error instanceof OffloadRefusal)) throw error;
|
|
1540
|
-
const refusal = error;
|
|
1541
|
-
phaseFailure = fail$1(refusal.code, refusal.message, refusal.remedy, { lastBuildStatus: true });
|
|
1542
|
-
return false;
|
|
1543
|
-
} finally {
|
|
1544
|
-
if (openOffload.choice) closeOffload(openOffload.choice);
|
|
1545
|
-
releaseHeldLock();
|
|
1546
|
-
releaseHeldSlot();
|
|
1547
1561
|
}
|
|
1548
|
-
|
|
1562
|
+
if (remote) uploadPending = uploadRemoteBuild({
|
|
1563
|
+
logWriter: writer,
|
|
1564
|
+
provider: remote.provider,
|
|
1565
|
+
platform: PLATFORM,
|
|
1566
|
+
projectRoot: root,
|
|
1567
|
+
fingerprintHash: storeHash,
|
|
1568
|
+
buildPath: artifactPath,
|
|
1569
|
+
runOptions: remoteRunOptions
|
|
1570
|
+
});
|
|
1549
1571
|
}
|
|
1550
|
-
|
|
1551
|
-
await
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1572
|
+
try {
|
|
1573
|
+
apkPath = await runArtifactLifecycle({
|
|
1574
|
+
resolve: async () => {
|
|
1575
|
+
if (!await resolveInitialFingerprint()) throw new ArtifactRefusal(phaseFailure);
|
|
1576
|
+
if (easBuild) return {
|
|
1577
|
+
kind: "ready",
|
|
1578
|
+
artifact: apkPath
|
|
1579
|
+
};
|
|
1580
|
+
await resolveRemoteArtifact();
|
|
1581
|
+
if (apkPath) return {
|
|
1582
|
+
kind: "cached",
|
|
1583
|
+
artifact: apkPath
|
|
1584
|
+
};
|
|
1585
|
+
miss(reasonForMiss([]).reason);
|
|
1586
|
+
return { kind: "miss" };
|
|
1587
|
+
},
|
|
1588
|
+
claim: useBuildCache ? awaitSharedBuild : void 0,
|
|
1589
|
+
reuse: async (cached) => {
|
|
1590
|
+
apkPath = await prepareCachedArtifact(cached);
|
|
1591
|
+
if (apkPath) lateHit();
|
|
1592
|
+
else if (swapFellBack) miss(reasonForMiss([]).reason);
|
|
1593
|
+
return apkPath;
|
|
1594
|
+
},
|
|
1595
|
+
build: {
|
|
1596
|
+
placement: {
|
|
1597
|
+
select: placeBuild,
|
|
1598
|
+
acquire: acquireRemoteArtifact
|
|
1599
|
+
},
|
|
1600
|
+
admit: async () => {
|
|
1601
|
+
if (!await takeBuildSlot()) throw new ArtifactRefusal(phaseFailure);
|
|
1602
|
+
},
|
|
1603
|
+
prepare: prepareSource,
|
|
1604
|
+
revalidate: revalidateSource,
|
|
1605
|
+
compile: compileHere,
|
|
1606
|
+
validate: validateCompiled,
|
|
1607
|
+
store: storeArtifact
|
|
1608
|
+
},
|
|
1609
|
+
release: () => {
|
|
1610
|
+
if (openOffload.choice) closeOffload(openOffload.choice);
|
|
1611
|
+
releaseHeldLock();
|
|
1612
|
+
releaseHeldSlot();
|
|
1613
|
+
}
|
|
1614
|
+
});
|
|
1615
|
+
} catch (error) {
|
|
1616
|
+
if (error instanceof OffloadRefusal) {
|
|
1617
|
+
const { code, message, remedy } = error;
|
|
1618
|
+
return {
|
|
1619
|
+
ok: false,
|
|
1620
|
+
failure: fail$1(code, message, remedy, { lastBuildStatus: true }),
|
|
1621
|
+
ccache: ccacheActivity
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
if (error instanceof ArtifactRefusal) return {
|
|
1625
|
+
ok: false,
|
|
1626
|
+
failure: error.failure,
|
|
1627
|
+
ccache: ccacheActivity
|
|
1628
|
+
};
|
|
1629
|
+
throw error;
|
|
1555
1630
|
}
|
|
1556
1631
|
return {
|
|
1557
1632
|
ok: true,
|
|
@@ -1655,11 +1730,41 @@ async function startCollector({ root, slot = "default", serial, packageName, spa
|
|
|
1655
1730
|
}
|
|
1656
1731
|
//#endregion
|
|
1657
1732
|
//#region src/commands/android/launch.ts
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1733
|
+
function androidProcessRuntime(prepare) {
|
|
1734
|
+
return {
|
|
1735
|
+
prepare,
|
|
1736
|
+
scheme: () => void 0,
|
|
1737
|
+
verificationWaitMs: RELEASE_VERIFY_WAIT_MS,
|
|
1738
|
+
launch: async (_prepared, { serial, androidPackage, remoteDevice, launchRelease }) => remoteDevice ? remoteDevice.launch({
|
|
1739
|
+
serial,
|
|
1740
|
+
packageName: androidPackage,
|
|
1741
|
+
metroPort: null
|
|
1742
|
+
}) : launchRelease({
|
|
1743
|
+
serial,
|
|
1744
|
+
packageName: androidPackage
|
|
1745
|
+
}),
|
|
1746
|
+
verify: async (_prepared, context) => verifyAndroidProcessRun(context)
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1749
|
+
function androidMetroRuntime(prepare) {
|
|
1750
|
+
return {
|
|
1751
|
+
prepare,
|
|
1752
|
+
scheme: (root, apkPath, resolve) => resolve(root, apkPath),
|
|
1753
|
+
verificationWaitMs: DEBUG_VERIFY_STEP_MS,
|
|
1754
|
+
launch: async ({ metroPort }, { serial, androidPackage, scheme, physical, launch }) => launch({
|
|
1755
|
+
serial,
|
|
1756
|
+
packageName: androidPackage,
|
|
1757
|
+
metroPort: metroPort ?? 8081,
|
|
1758
|
+
devClientScheme: scheme,
|
|
1759
|
+
physical
|
|
1760
|
+
}),
|
|
1761
|
+
verify: async ({ metroPort }, context) => verifyAndroidMetroRun({
|
|
1762
|
+
...context,
|
|
1763
|
+
metroPort
|
|
1764
|
+
})
|
|
1765
|
+
};
|
|
1766
|
+
}
|
|
1767
|
+
async function verifyAndroidProcessRun({ root, slot, remoteDevice, verifyReleaseLaunched, serial, androidPackage, variant, logsDir, launchedAt, phase }) {
|
|
1663
1768
|
const readNativeCrashes = () => remoteDevice ? [] : captureNativeCrashes({
|
|
1664
1769
|
root,
|
|
1665
1770
|
slot,
|
|
@@ -1668,30 +1773,42 @@ async function verifyAndroidRun({ root, slot, release, remoteRelease, remoteDevi
|
|
|
1668
1773
|
appId: androidPackage,
|
|
1669
1774
|
since: launchedAt
|
|
1670
1775
|
}, logsDir);
|
|
1671
|
-
if (
|
|
1776
|
+
if (remoteDevice) {
|
|
1672
1777
|
phase("verify", chalk.yellow("UNVERIFIED: remote adapter launch accepted; process verification is unavailable"));
|
|
1673
1778
|
return { state: LAUNCH_UNVERIFIED };
|
|
1674
1779
|
}
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
return { state: LAUNCH_UNVERIFIED };
|
|
1688
|
-
}
|
|
1689
|
-
for (const line of launchErrorPreview(crashes, root)) phase("launch", chalk.red(line));
|
|
1690
|
-
if (!crashes.length) phase("logs", "Process missing; no attributable native crash report captured. Read `stim logs --source device` for available output.");
|
|
1691
|
-
phase("verify", chalk.yellow(crashes.length ? "FATAL: the app reported a native crash" : `FATAL: no ${androidPackage} process on ${serial} ${formatDuration(processCheck?.waitedMs ?? 0)} after launch`));
|
|
1692
|
-
phase("", chalk.yellow("A release process exited before readiness. Run `stim logs --errors` for captured crash reports, or `stim logs --source device` for the full device output."));
|
|
1693
|
-
return { state: LAUNCH_FATAL };
|
|
1780
|
+
const processCheck = await verifyReleaseLaunched({
|
|
1781
|
+
serial,
|
|
1782
|
+
packageName: androidPackage
|
|
1783
|
+
});
|
|
1784
|
+
const crashes = readNativeCrashes();
|
|
1785
|
+
if (processCheck?.verified && !crashes.length) {
|
|
1786
|
+
phase("verify", `process alive ${formatDuration(processCheck.waitedMs ?? 0)} after launch (${variant}: no bundle fetch to observe)`);
|
|
1787
|
+
return { state: true };
|
|
1788
|
+
}
|
|
1789
|
+
if (processCheck?.reason === "probe-failed" && !crashes.length) {
|
|
1790
|
+
phase("verify", chalk.yellow("UNVERIFIED: the app process check failed"));
|
|
1791
|
+
return { state: LAUNCH_UNVERIFIED };
|
|
1694
1792
|
}
|
|
1793
|
+
for (const line of launchErrorPreview(crashes, root)) phase("launch", chalk.red(line));
|
|
1794
|
+
if (!crashes.length) phase("logs", "Process missing; no attributable native crash report captured. Read `stim logs --source device` for available output.");
|
|
1795
|
+
phase("verify", chalk.yellow(crashes.length ? "FATAL: the app reported a native crash" : `FATAL: no ${androidPackage} process on ${serial} ${formatDuration(processCheck?.waitedMs ?? 0)} after launch`));
|
|
1796
|
+
phase("", chalk.yellow("A release process exited before readiness. Run `stim logs --errors` for captured crash reports, or `stim logs --source device` for the full device output."));
|
|
1797
|
+
return { state: LAUNCH_FATAL };
|
|
1798
|
+
}
|
|
1799
|
+
async function verifyAndroidMetroRun({ root, slot, remoteDevice, verifyLaunched, serial, androidPackage, metroCheck, logsDir, launchedAt, metroPort, isExpo, physical, device, scheme, component = null, phase }) {
|
|
1800
|
+
const runCommand = nativeRunCommand("android", slot, {
|
|
1801
|
+
physical,
|
|
1802
|
+
deviceId: serial
|
|
1803
|
+
});
|
|
1804
|
+
const readNativeCrashes = () => remoteDevice ? [] : captureNativeCrashes({
|
|
1805
|
+
root,
|
|
1806
|
+
slot,
|
|
1807
|
+
platform: "android",
|
|
1808
|
+
deviceId: serial,
|
|
1809
|
+
appId: androidPackage,
|
|
1810
|
+
since: launchedAt
|
|
1811
|
+
}, logsDir);
|
|
1695
1812
|
const freshEmulator = Boolean((device.created || device.adoptionPending) && device.owned && !remoteDevice);
|
|
1696
1813
|
const timeoutMs = freshEmulator ? 6e4 : VERIFY_TIMEOUT_MS;
|
|
1697
1814
|
if (metroCheck && freshEmulator) phase("verify", `waiting up to 60s for bundle load (${device.created ? "new" : "adopted"} emulator)`);
|
|
@@ -1866,7 +1983,7 @@ async function resolveInstallSerial({ root, slot, device, physical, remoteDevice
|
|
|
1866
1983
|
});
|
|
1867
1984
|
return resolved.serial;
|
|
1868
1985
|
}
|
|
1869
|
-
async function finishAndroidRun({ lease, releaseLease, root, slot, json, metroCheck, useBuildCache, variant, release, isExpo, metroPort, logsDir, emuLog, device, physical, remoteDevice, bootPromise, resolveAvdSerial, waitForDeviceBoot, bootDuration, apkPath, androidPackage: initialPackage, swapDir, record, waitedForBuild, ccache, uploadPending, providerUpload, providerName, remote, abandonedRemote: remoteWasAbandoned, started, startedAt, writer, phase, fail, readApkPackage, install, launch, launchRelease, resolveDevClientScheme, verifyLaunched, verifyReleaseLaunched, spawn, kill, pidAlive, verifyCollector, writeLaunch, recordBuild, now, out, emit, recordRun, reclaimed, devServer, enterPhase, rebootDevice, dataFreeBytes = androidDataFreeBytes, trimCaches = trimAndroidCaches, wipeDevice = teardownOwnedAvd }) {
|
|
1986
|
+
async function finishAndroidRun({ runtime, runtimePreparation, lease, releaseLease, root, slot, json, metroCheck, useBuildCache, variant, release, isExpo, metroPort, logsDir, emuLog, device, physical, remoteDevice, bootPromise, resolveAvdSerial, waitForDeviceBoot, bootDuration, apkPath, androidPackage: initialPackage, swapDir, record, waitedForBuild, ccache, uploadPending, providerUpload, providerName, remote, abandonedRemote: remoteWasAbandoned, started, startedAt, writer, phase, fail, readApkPackage, install, launch, launchRelease, resolveDevClientScheme, verifyLaunched, verifyReleaseLaunched, spawn, kill, pidAlive, verifyCollector, writeLaunch, recordBuild, now, out, emit, recordRun, reclaimed, devServer, enterPhase, rebootDevice, dataFreeBytes = androidDataFreeBytes, trimCaches = trimAndroidCaches, wipeDevice = teardownOwnedAvd }) {
|
|
1870
1987
|
let androidPackage = initialPackage;
|
|
1871
1988
|
let leaseWarned = false;
|
|
1872
1989
|
const raiseLeaseFor = (boundMs, beforeInstall) => {
|
|
@@ -1998,7 +2115,7 @@ async function finishAndroidRun({ lease, releaseLease, root, slot, json, metroCh
|
|
|
1998
2115
|
record.bundleId = androidPackage;
|
|
1999
2116
|
if (!androidPackage) return fail(LAUNCH_FAILED, "Could not determine this app's Android package name, so there is nothing to launch.", "Set `expo.android.package` in app.json / app.config.js, or `namespace` in android/app/build.gradle.", { lastBuildStatus: true });
|
|
2000
2117
|
if (physical) raiseLeaseFor(0, false);
|
|
2001
|
-
const scheme =
|
|
2118
|
+
const scheme = runtime.scheme(root, apkPath, resolveDevClientScheme);
|
|
2002
2119
|
enterPhase("launch");
|
|
2003
2120
|
const launchTimer = stepTimer(now);
|
|
2004
2121
|
const launchedAt = now();
|
|
@@ -2015,19 +2132,14 @@ async function finishAndroidRun({ lease, releaseLease, root, slot, json, metroCh
|
|
|
2015
2132
|
physical,
|
|
2016
2133
|
msg: `launching ${androidPackage} on ${serial}`
|
|
2017
2134
|
});
|
|
2018
|
-
const launched =
|
|
2019
|
-
serial,
|
|
2020
|
-
packageName: androidPackage,
|
|
2021
|
-
metroPort: null
|
|
2022
|
-
}) : launchRelease({
|
|
2135
|
+
const launched = await runtime.launch(runtimePreparation, {
|
|
2023
2136
|
serial,
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
physical
|
|
2137
|
+
androidPackage,
|
|
2138
|
+
scheme,
|
|
2139
|
+
physical,
|
|
2140
|
+
remoteDevice,
|
|
2141
|
+
launch,
|
|
2142
|
+
launchRelease
|
|
2031
2143
|
});
|
|
2032
2144
|
if (launched.failed) {
|
|
2033
2145
|
printNativeCrashReport({
|
|
@@ -2118,12 +2230,10 @@ async function finishAndroidRun({ lease, releaseLease, root, slot, json, metroCh
|
|
|
2118
2230
|
});
|
|
2119
2231
|
phase("logs", `${displayPath(root, logsDir)}${collectorPid ? ` (collector pid ${collectorPid})` : ""}`);
|
|
2120
2232
|
}
|
|
2121
|
-
if (physical) raiseLeaseFor(
|
|
2122
|
-
const { state: launchState, warning: launchWarning, unattributed } = await
|
|
2233
|
+
if (physical) raiseLeaseFor(runtime.verificationWaitMs, false);
|
|
2234
|
+
const { state: launchState, warning: launchWarning, unattributed } = await runtime.verify(runtimePreparation, {
|
|
2123
2235
|
root,
|
|
2124
2236
|
slot,
|
|
2125
|
-
release,
|
|
2126
|
-
remoteRelease,
|
|
2127
2237
|
remoteDevice: Boolean(remoteDevice),
|
|
2128
2238
|
verifyReleaseLaunched,
|
|
2129
2239
|
verifyLaunched,
|
|
@@ -2446,7 +2556,7 @@ function androidDeviceSelectorRefusal({ settingsContext, slot, systemImageFlag,
|
|
|
2446
2556
|
//#endregion
|
|
2447
2557
|
//#region src/commands/android/next-build.ts
|
|
2448
2558
|
const DEFAULT_PLAN_DEPS = {
|
|
2449
|
-
findRoot: findProjectRoot
|
|
2559
|
+
findRoot: findProjectRoot,
|
|
2450
2560
|
fingerprint: fingerprintProject,
|
|
2451
2561
|
listSystemImages: listInstalledSystemImages,
|
|
2452
2562
|
avdSystemImage: ownedAvdSystemImage,
|
|
@@ -2511,10 +2621,10 @@ async function planAndroid(opts, overrides = {}) {
|
|
|
2511
2621
|
if (flag) return refuse(planFlagRefusal(flag));
|
|
2512
2622
|
const root = deps.findRoot(process.cwd());
|
|
2513
2623
|
if (!root) return refuse(NO_PROJECT_REFUSAL);
|
|
2514
|
-
const
|
|
2515
|
-
if (
|
|
2624
|
+
const problem = projectProblem(root, "android");
|
|
2625
|
+
if (problem) return refuse({
|
|
2516
2626
|
code: "STIM_NO_PROJECT",
|
|
2517
|
-
...
|
|
2627
|
+
...problem
|
|
2518
2628
|
});
|
|
2519
2629
|
const slot = validateDeviceSlot(opts.slot);
|
|
2520
2630
|
const settingsContext = {
|
|
@@ -2522,8 +2632,9 @@ async function planAndroid(opts, overrides = {}) {
|
|
|
2522
2632
|
gitCommonDir: gitCommonDir(root),
|
|
2523
2633
|
repoRoot: repoRoot(root)
|
|
2524
2634
|
};
|
|
2635
|
+
const settings = resolveSettings(settingsContext);
|
|
2525
2636
|
const planned = resolveAndroidRunPlan({
|
|
2526
|
-
settings
|
|
2637
|
+
settings,
|
|
2527
2638
|
settingsContext,
|
|
2528
2639
|
slot,
|
|
2529
2640
|
easProfile: opts.easProfile,
|
|
@@ -2608,7 +2719,17 @@ async function planAndroid(opts, overrides = {}) {
|
|
|
2608
2719
|
const local = localImage();
|
|
2609
2720
|
if ("refusal" in local || !("systemImage" in choice)) return null;
|
|
2610
2721
|
return androidSystemImageAbi(local.systemImage) === androidSystemImageAbi(choice.systemImage);
|
|
2611
|
-
}
|
|
2722
|
+
},
|
|
2723
|
+
...remoteEasFallbackSetting(settings) ? { eas: () => checkEasFallback({
|
|
2724
|
+
root,
|
|
2725
|
+
platform: "android",
|
|
2726
|
+
slot,
|
|
2727
|
+
release: build.release,
|
|
2728
|
+
isExpo,
|
|
2729
|
+
tunnelMode: tunnelModeSetting(settings),
|
|
2730
|
+
publicUrl: publicUrlSetting(settings),
|
|
2731
|
+
localOnlyFlags: typeof opts.systemImage === "string" ? ["--system-image"] : []
|
|
2732
|
+
}) } : {}
|
|
2612
2733
|
});
|
|
2613
2734
|
if (hostedPlan.kind === "unknown") return refuse({
|
|
2614
2735
|
code: "STIM_BAD_ARG",
|
|
@@ -2669,12 +2790,12 @@ function androidCommand(program) {
|
|
|
2669
2790
|
registerAndroid(program);
|
|
2670
2791
|
}
|
|
2671
2792
|
function registerAndroid(program) {
|
|
2672
|
-
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) => {
|
|
2673
|
-
if (!parseMachine(value)) throw new InvalidArgumentError("expected eas, proxy, auto, or a tailnet machine name");
|
|
2793
|
+
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; local runs here, whatever android.remote says", (value) => {
|
|
2794
|
+
if (!parseMachine(value)) throw new InvalidArgumentError("expected eas, proxy, auto, local, or a tailnet machine name");
|
|
2674
2795
|
return value;
|
|
2675
2796
|
}).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) => {
|
|
2676
2797
|
if (opts.plan) return planAndroid(opts);
|
|
2677
|
-
const root = findProjectRoot
|
|
2798
|
+
const root = findProjectRoot(process.cwd());
|
|
2678
2799
|
if (!root) {
|
|
2679
2800
|
refuseNoProject({ json: Boolean(opts.json) });
|
|
2680
2801
|
return;
|
|
@@ -2876,9 +2997,9 @@ async function runAndroid(options = {}) {
|
|
|
2876
2997
|
const slot = validateDeviceSlot(options.slot);
|
|
2877
2998
|
const started = now();
|
|
2878
2999
|
const startedAt = new Date(started).toISOString();
|
|
2879
|
-
const
|
|
2880
|
-
if (
|
|
2881
|
-
const { message, remedy } =
|
|
3000
|
+
const problem = projectProblem(root, "android");
|
|
3001
|
+
if (problem) {
|
|
3002
|
+
const { message, remedy } = problem;
|
|
2882
3003
|
out(phaseLine("error", chalk.red(`STIM_NO_PROJECT: ${message}`)));
|
|
2883
3004
|
out(phaseLine("remedy", remedy));
|
|
2884
3005
|
if (json) emit(JSON.stringify({
|
|
@@ -3041,6 +3162,7 @@ async function runAndroid(options = {}) {
|
|
|
3041
3162
|
if (!planned.ok) return fail(planned.code, planned.message, planned.remedy, { lines: planned.lines });
|
|
3042
3163
|
const { plan } = planned;
|
|
3043
3164
|
const deviceSlotWait = {
|
|
3165
|
+
automatic: plan.target.kind === "hosted" && plan.target.machine === "auto",
|
|
3044
3166
|
signal: runCancellationSignal(),
|
|
3045
3167
|
waitMs: plan.deviceSlotWaitMs,
|
|
3046
3168
|
displayName: basename(root),
|
|
@@ -3066,6 +3188,16 @@ async function runAndroid(options = {}) {
|
|
|
3066
3188
|
resolveSerial: resolveAvdSerial,
|
|
3067
3189
|
prepare: options.prepareHostedAndroid,
|
|
3068
3190
|
automatic: options.automaticDevicePlacement,
|
|
3191
|
+
...remoteEasFallbackSetting(settings) ? { eas: () => (options.checkEasFallback ?? checkEasFallback)({
|
|
3192
|
+
root,
|
|
3193
|
+
platform: PLATFORM,
|
|
3194
|
+
slot,
|
|
3195
|
+
release,
|
|
3196
|
+
isExpo,
|
|
3197
|
+
tunnelMode: tunnelModeSetting(settings),
|
|
3198
|
+
publicUrl: publicUrlSetting(settings),
|
|
3199
|
+
localOnlyFlags: [...typeof systemImageFlag === "string" ? ["--system-image"] : [], ...typeof deviceProfileFlag === "string" ? ["--device-profile"] : []]
|
|
3200
|
+
}) } : {},
|
|
3069
3201
|
localSelectors: (target) => androidDeviceSelectorRefusal({
|
|
3070
3202
|
settingsContext,
|
|
3071
3203
|
slot,
|
|
@@ -3130,10 +3262,8 @@ async function runAndroid(options = {}) {
|
|
|
3130
3262
|
const reservedPort = project?.metroPort ?? null;
|
|
3131
3263
|
let metroPort = null;
|
|
3132
3264
|
let devServer = null;
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
if (release) phase("metro", `skipped (${variant}: the JS bundle is embedded, no dev server is used)`);
|
|
3136
|
-
else if (metroCheck) {
|
|
3265
|
+
async function prepareMetro() {
|
|
3266
|
+
if (metroCheck) {
|
|
3137
3267
|
const gate = await ensureDevServer({
|
|
3138
3268
|
root,
|
|
3139
3269
|
port: reservedPort,
|
|
@@ -3145,27 +3275,54 @@ async function runAndroid(options = {}) {
|
|
|
3145
3275
|
readState
|
|
3146
3276
|
});
|
|
3147
3277
|
reclaimed = [...reclaimed, ...gate.reclaimed];
|
|
3148
|
-
if (!gate.ok) {
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3278
|
+
if (!gate.ok) return {
|
|
3279
|
+
ok: false,
|
|
3280
|
+
error: {
|
|
3281
|
+
code: gate.code,
|
|
3282
|
+
message: gate.message,
|
|
3283
|
+
remedy: gate.remedy,
|
|
3284
|
+
lines: gate.lines
|
|
3285
|
+
}
|
|
3286
|
+
};
|
|
3152
3287
|
metroPort = gate.port;
|
|
3153
3288
|
devServer = gate.devServer;
|
|
3154
3289
|
phase("metro", `port ${metroPort} (${devServer ? `started: ${devServer.reason}` : `pid ${gate.pid ?? "unknown, started outside Stim"}`})`);
|
|
3155
|
-
return
|
|
3290
|
+
return {
|
|
3291
|
+
ok: true,
|
|
3292
|
+
prepared: { metroPort }
|
|
3293
|
+
};
|
|
3156
3294
|
} else {
|
|
3157
3295
|
const pin = metroPortSetting(root);
|
|
3158
|
-
if (pin.error) {
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3296
|
+
if (pin.error) return {
|
|
3297
|
+
ok: false,
|
|
3298
|
+
error: {
|
|
3299
|
+
code: "STIM_BAD_ARG",
|
|
3300
|
+
message: pin.error,
|
|
3301
|
+
remedy: SETTING_SHAPE_REMEDY
|
|
3302
|
+
}
|
|
3303
|
+
};
|
|
3162
3304
|
metroPort = pin.port ?? reservedPort ?? 8081;
|
|
3163
3305
|
phase("metro", pin.port ?? reservedPort ? `port ${metroPort} (not checked)` : `no reservation; using ${DEFAULT_METRO_PORT} (not checked)`);
|
|
3164
3306
|
}
|
|
3165
|
-
|
|
3166
|
-
|
|
3307
|
+
return {
|
|
3308
|
+
ok: true,
|
|
3309
|
+
prepared: { metroPort }
|
|
3310
|
+
};
|
|
3167
3311
|
}
|
|
3168
|
-
|
|
3312
|
+
const runtime = options.runtimePlan ?? (release ? androidProcessRuntime(async () => {
|
|
3313
|
+
phase("metro", `skipped (${variant}: the JS bundle is embedded, no dev server is used)`);
|
|
3314
|
+
return {
|
|
3315
|
+
ok: true,
|
|
3316
|
+
prepared: { metroPort: null }
|
|
3317
|
+
};
|
|
3318
|
+
}) : androidMetroRuntime(prepareMetro));
|
|
3319
|
+
const preparation = await runtime.prepare();
|
|
3320
|
+
if (!preparation.ok) {
|
|
3321
|
+
const { code, message, remedy, lines } = preparation.error;
|
|
3322
|
+
return fail(code, message, remedy, { lines });
|
|
3323
|
+
}
|
|
3324
|
+
const runtimePreparation = preparation.prepared;
|
|
3325
|
+
metroPort = runtimePreparation.metroPort;
|
|
3169
3326
|
if (remoteContext) {
|
|
3170
3327
|
remoteDevice = makeRemoteDeviceDeps(remoteContext.ctx);
|
|
3171
3328
|
if (metroPort !== null) {
|
|
@@ -3406,6 +3563,7 @@ async function runAndroid(options = {}) {
|
|
|
3406
3563
|
record,
|
|
3407
3564
|
fail,
|
|
3408
3565
|
phase,
|
|
3566
|
+
enterPhase: progress.step,
|
|
3409
3567
|
out,
|
|
3410
3568
|
json,
|
|
3411
3569
|
useBuildCache,
|
|
@@ -3480,6 +3638,8 @@ async function runAndroid(options = {}) {
|
|
|
3480
3638
|
}
|
|
3481
3639
|
try {
|
|
3482
3640
|
return await finishAndroidRun({
|
|
3641
|
+
runtime,
|
|
3642
|
+
runtimePreparation,
|
|
3483
3643
|
slot,
|
|
3484
3644
|
lease: leaseHandle,
|
|
3485
3645
|
releaseLease,
|