stim 1.14.0 → 1.16.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 +2 -0
- package/dist/activity-BxwdD81S.mjs +609 -0
- package/dist/agent-device-usage-output-Dpih1Tfa.mjs +411 -0
- package/dist/{android-d6rGq1pA.mjs → android-B_NumVyQ.mjs} +169 -81
- package/dist/{android-LbPFRWVL.mjs → android-Ift4kVvt.mjs} +517 -413
- package/dist/android-cas-8U4DPqeR.mjs +167 -0
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{android-XpvCrV7q.mjs → android-r2rBL8kV.mjs} +2 -2
- package/dist/{app-install-BpgSgkJj.mjs → app-install-CKWdbXIX.mjs} +128 -151
- package/dist/attempt-Bk2ouQVL.mjs +39 -0
- package/dist/budget-DjrURfQn.mjs +2700 -0
- package/dist/{build-plan-Dcr-3ie0.mjs → build-plan-DjeSb2Xl.mjs} +192 -653
- package/dist/build-slots-rUk77xqh.mjs +132 -0
- package/dist/{cache-manifest-C68QQ0ua.mjs → cache-manifest-DnUHBJaU.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{chrome-BPCiC3ZX.mjs → chrome-BrcVWQyD.mjs} +1 -1
- package/dist/cli-BkYZ_6hy.mjs +51 -0
- package/dist/cli.mjs +6 -42
- package/dist/client-BTY686R6.mjs +1368 -0
- package/dist/collector-run.mjs +9 -195
- package/dist/{command-output-DVcpw6eE.mjs → command-output-DnJMdEY-.mjs} +1 -1
- package/dist/{config-lvc7d3C2.mjs → config-D0DbpZtM.mjs} +28 -29
- package/dist/{created-devices-CllH_8eb.mjs → created-devices-D5owjN4C.mjs} +2 -2
- package/dist/{dependency-state-DsT7aKeo.mjs → dependency-state-B6cMXZab.mjs} +2 -2
- package/dist/{deps-D9IcKqXS.mjs → deps-urbmfXig.mjs} +3 -3
- package/dist/{detached-entry-DJHoca49.mjs → detached-entry-CiTEgMR1.mjs} +1 -1
- package/dist/dev-client-CroAIjjj.mjs +43 -0
- package/dist/{device-CjuuAJjQ.mjs → device-DZQjF7H5.mjs} +8 -7
- package/dist/device-capacity-BHwxNBlu.mjs +136 -0
- package/dist/device-host-worker.d.mts +1 -0
- package/dist/device-host-worker.mjs +964 -0
- package/dist/device-ios-BadmeL2V.mjs +381 -0
- package/dist/{device-lease-5c3WrVRm.mjs → device-lease-D-hLqx1b.mjs} +43 -36
- package/dist/{device-pool-BiyDyPP-.mjs → device-lease-run-CqjShqWW.mjs} +6 -126
- package/dist/device-pool-CUaEWMMm.mjs +125 -0
- package/dist/{device-remote-D87zEzaq.mjs → device-remote-D5WVWqOq.mjs} +69 -163
- package/dist/{doctor-x9pnU9fq.mjs → doctor-Cimf-gGB.mjs} +241 -103
- package/dist/{error-diagnostics-C5HzcwCW.mjs → error-diagnostics-B9L4Ae0x.mjs} +15 -18
- package/dist/{exec-DK8KaVHK.mjs → exec-CaErVv7t.mjs} +5 -1
- package/dist/{gc-ko6mUAYD.mjs → gc-Bqy4bjEu.mjs} +599 -108
- package/dist/{android-cas-iZK3DOCr.mjs → gradle-BsO1MdsH.mjs} +8 -294
- package/dist/{guide-6R0VNFqI.mjs → guide-B_uyKTxW.mjs} +2511 -239
- package/dist/{guide-status-BZrFPIA_.mjs → guide-status-CjEZMAD4.mjs} +3 -3
- package/dist/hosted-client-a-WmqE2L.mjs +197 -0
- package/dist/hosted-ios-CIWelIqf.mjs +220 -0
- package/dist/hosted-logs-D5g041Q3.mjs +187 -0
- package/dist/hosted-macos-BSZyIb3y.mjs +135 -0
- package/dist/idle-DYVymG92.mjs +1099 -0
- package/dist/idle-shutdown-CTsDnAde.mjs +122 -0
- package/dist/in-use-DvBw0Kxo.mjs +130 -0
- package/dist/{ios-BwDPrnYQ.mjs → ios-BaInn3sW.mjs} +201 -10
- package/dist/ios-Cr1h5gnO.mjs +189 -0
- package/dist/{ios-P1f5nm2n.mjs → ios-aq3QoGI3.mjs} +1159 -633
- package/dist/{ios-device-BiOsSVzd.mjs → ios-device-Ee7sDXfp.mjs} +1 -1
- package/dist/{ios-device-DGglU3E_.mjs → ios-device-FfCN_C8p.mjs} +12 -7
- package/dist/ios-state-DS5UpYTH.mjs +48 -0
- package/dist/{launch-verify-Deg4tB3Z.mjs → launch-verify-2DBRizjo.mjs} +5 -5
- package/dist/logs-CHEVK8zD.mjs +371 -0
- package/dist/machines-BIBUdhpj.mjs +265 -0
- package/dist/macos-CSYEAFmF.mjs +473 -0
- package/dist/macos-run.d.mts +5 -0
- package/dist/macos-run.mjs +2 -0
- package/dist/maintenance-run.d.mts +4 -0
- package/dist/maintenance-run.mjs +254 -0
- package/dist/{metro-CcEo8Fl8.mjs → metro-BeK1ZPz1.mjs} +20 -120
- package/dist/metro-gateway-BJ-rxQAB.mjs +84 -0
- package/dist/{named-ports-Blg8IxOh.mjs → named-ports-Bk_YXEmE.mjs} +6 -59
- package/dist/native-run-NaBrRFtQ.mjs +147 -0
- package/dist/{native-runtime-DjBHRg5m.mjs → native-runtime-DBzRnEKS.mjs} +9 -5
- package/dist/{ndjson-CDY9IkVC.mjs → ndjson-PclOIwVY.mjs} +2 -2
- package/dist/offload-worker.d.mts +122 -0
- package/dist/offload-worker.mjs +606 -0
- package/dist/{ownership-DyYDF5ww.mjs → ownership-DiA16AsN.mjs} +3 -2
- package/dist/ownership-hCkPzGmr.mjs +571 -0
- package/dist/{page-BHUzTDFt.mjs → page-QF_Ke10s.mjs} +7 -2
- package/dist/{ports-BguS83ex.mjs → ports-R2k4Knz3.mjs} +3 -3
- package/dist/prebuild-D2fsca_Z.mjs +213 -0
- package/dist/preview-DhVbvPAZ.mjs +318 -0
- package/dist/process-identity-BmRm1qV0.mjs +12 -0
- package/dist/{project-CWlvEaeN.mjs → project-Du91Ilvc.mjs} +74 -19
- package/dist/pull-request-pxnDCQzn.mjs +322 -0
- package/dist/pull-requests.d.mts +120 -0
- package/dist/pull-requests.mjs +2 -0
- package/dist/recordings-BIXOzVnr.mjs +37 -0
- package/dist/{reload-BiniwsSZ.mjs → reload-rM9jV1fz.mjs} +109 -24
- package/dist/{remote-cache-CcR6o6lI.mjs → remote-cache-C8-V13XN.mjs} +5 -5
- package/dist/run-f4vI6EnK.mjs +119 -0
- package/dist/{server-bare-DGfgyJ5J.mjs → server-bare-CpPGmnmO.mjs} +33 -15
- package/dist/server-expo-CVqO2c35.mjs +2 -0
- package/dist/{server-expo-BVuwQ65v.mjs → server-expo-MC0rHlOC.mjs} +8 -12
- package/dist/settings-BBpMcDbD.mjs +25 -0
- package/dist/{settings-B-fsC-Om.mjs → settings-ZkDzkzvB.mjs} +22 -10
- package/dist/settings-oTSkkNrM.mjs +1439 -0
- package/dist/settings.schema.json +845 -97
- package/dist/{simslim-DrDN4WuV.mjs → simslim-B8-7AoTI.mjs} +8 -132
- package/dist/{slot-launch-D5t8EiMf.mjs → slot-launch-B8VrHxn1.mjs} +11 -8
- package/dist/{spawn-claims-Drw_o-Fb.mjs → spawn-claims-D0XfSe8u.mjs} +1 -1
- package/dist/spawn-entry-jw19m8Nl.mjs +17 -0
- package/dist/stage-CzaiwFsI.mjs +143 -0
- package/dist/start-CX8Ig-U2.mjs +2 -0
- package/dist/{start-s4RXp1wy.mjs → start-ClDfwXa4.mjs} +116 -65
- package/dist/state-3DwSQIBK.mjs +41 -0
- package/dist/state-B4PQFXMW.d.mts +12 -0
- package/dist/{state-Dk9RVXI7.mjs → state-C1jB7Q8q.mjs} +70 -8
- package/dist/{state-DHqvsbqC.mjs → state-DcW6vOd_.mjs} +7 -4
- package/dist/stats-CEZ_i5je.mjs +77 -0
- package/dist/{status-BgAuxESg.mjs → status-BuvBFeII.mjs} +118 -20
- package/dist/{status-BsPAnfOI.mjs → status-Cs7VLg9D.mjs} +542 -283
- package/dist/status-DlKvVJBE.mjs +49 -0
- package/dist/stdout-reader-C8yjre1x.mjs +23 -0
- package/dist/stim-desktop-Cnz8CPnl.mjs +63 -0
- package/dist/stim-footprint.swift +32 -0
- package/dist/{stim-installations-CINXy_su.mjs → stim-installations-QMEI32v1.mjs} +1 -1
- package/dist/stop-B0Yxtmiy.mjs +48 -0
- package/dist/{stop-BzreOWJp.mjs → stop-Bffozsac.mjs} +83 -16
- package/dist/{stop-BWIF_6BK.mjs → stop-Dt_dM16A.mjs} +2 -2
- package/dist/stop-cause-CidxIqup.mjs +97 -0
- package/dist/supervisor-run.d.mts +43 -11
- package/dist/supervisor-run.mjs +363 -24
- package/dist/support-CAP8qDUF.mjs +316 -0
- package/dist/support-D4aYJniO.mjs +201 -0
- package/dist/teardown-CL6vDs2Y.mjs +727 -0
- package/dist/{xcode-Cp5KvK9x.mjs → toolchain-DkUflduf.mjs} +364 -14
- package/dist/trigger-Bemu8ytw.mjs +65 -0
- package/dist/trigger-CXts6qt1.mjs +2 -0
- package/dist/warm-progress-CpGv3Wb6.mjs +732 -0
- package/dist/{web-BsQs1WlO.mjs → web-DWUaMp8P.mjs} +37 -21
- package/dist/web-run.mjs +310 -13
- package/dist/workspace-process-lock-BL7Q0HCO.mjs +57 -0
- package/dist/workspace-state-B8-aJ1_5.mjs +371 -0
- package/dist/workspaces-BV4pdHFz.mjs +306 -0
- package/dist/{worktree-UrQWXSeb.mjs → worktree-K-xj9Db0.mjs} +625 -256
- package/dist/worktree-jnG8Iph5.mjs +2 -0
- package/package.json +10 -5
- package/shim/bundle-response.cjs +28 -12
- package/dist/activity-CYVDcrt3.mjs +0 -356
- package/dist/budget-CGDkhvv_.mjs +0 -1745
- package/dist/build-progress-DxKpwnaS.mjs +0 -247
- package/dist/idle-DXtx3RbX.mjs +0 -191
- package/dist/in-use-DlqBDKqY.mjs +0 -249
- package/dist/logs-Civ4gbBH.mjs +0 -486
- package/dist/merge-state-ytFQCeh4.mjs +0 -262
- package/dist/server-expo-DIHDhvGg.mjs +0 -2
- package/dist/settings-D61iNOsB.mjs +0 -629
- package/dist/start-Cetfvy8l.mjs +0 -2
- package/dist/stats-CFpFGlJV.mjs +0 -62
- package/dist/stats-CX1Z8Tca.mjs +0 -368
- package/dist/stim-desktop-CXt8-Z3J.mjs +0 -40
- package/dist/stop-cause-hjGBOZTG.mjs +0 -1231
- package/dist/worktree-BVrHsYZG.mjs +0 -752
- package/dist/worktree-CHWWvm5v.mjs +0 -2
- package/dist/{metro-store-DzeWkfqW.mjs → metro-store-CDDZHtPl.mjs} +1 -1
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { t as getExecutor } from "./exec-CaErVv7t.mjs";
|
|
2
|
+
import { C as emulatorFailureRemedy, D as hostSystemImageArch, K as profileNeedsFoldFeature, N as memoizeEmulatorProbe, S as emulatorDiskSpaceRemedy, T as findBuildTool, W as pickDefaultSystemImage, c as androidPoolNoCandidatesRefusal, l as androidSystemImageAbi, o as androidHome, s as androidPoolCandidates, w as extractEmulatorFailure } from "./android-B_NumVyQ.mjs";
|
|
3
|
+
import { C as pickDevClientScheme } from "./app-install-CKWdbXIX.mjs";
|
|
4
|
+
import { o as unknownAndroidDeviceProfileRefusal, r as layerNote, s as unknownAndroidSystemImageRefusal } from "./device-capacity-BHwxNBlu.mjs";
|
|
5
|
+
import { t as devClientScheme } from "./dev-client-CroAIjjj.mjs";
|
|
6
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
7
|
+
import { relative } from "node:path";
|
|
8
|
+
//#region src/commands/android/support.ts
|
|
9
|
+
const PLATFORM = "android";
|
|
10
|
+
function androidVariantSetting(settings) {
|
|
11
|
+
const android = settings?.["android"];
|
|
12
|
+
if (!android || typeof android !== "object" || Array.isArray(android)) return null;
|
|
13
|
+
const raw = android["variant"];
|
|
14
|
+
return typeof raw === "string" && raw.trim() !== "" ? raw.trim() : null;
|
|
15
|
+
}
|
|
16
|
+
function resolveVariant(flag, settings) {
|
|
17
|
+
return (typeof flag === "string" && flag.trim() !== "" ? flag.trim() : null) || androidVariantSetting(settings);
|
|
18
|
+
}
|
|
19
|
+
function androidSystemImageSetting(settings) {
|
|
20
|
+
const android = settings?.["android"];
|
|
21
|
+
if (!android || typeof android !== "object" || Array.isArray(android)) return null;
|
|
22
|
+
const raw = android["systemImage"];
|
|
23
|
+
return typeof raw === "string" && raw.trim() !== "" ? raw.trim() : null;
|
|
24
|
+
}
|
|
25
|
+
function resolveSystemImage(flag, settings) {
|
|
26
|
+
return (typeof flag === "string" && flag.trim() !== "" ? flag.trim() : null) || androidSystemImageSetting(settings);
|
|
27
|
+
}
|
|
28
|
+
function remoteAvdFlagRefusal({ systemImageFlag, deviceProfileFlag, remoteBackend }) {
|
|
29
|
+
if (!remoteBackend) return null;
|
|
30
|
+
const given = [typeof systemImageFlag === "string" && "--system-image", typeof deviceProfileFlag === "string" && "--device-profile"].filter(Boolean).join(" and ");
|
|
31
|
+
if (!given) return null;
|
|
32
|
+
return {
|
|
33
|
+
code: "STIM_BAD_ARG",
|
|
34
|
+
message: `${given} ${given.includes(" and ") ? "apply" : "applies"} only to a local owned Android emulator; the ${remoteBackend} remote backend chooses its own device.`,
|
|
35
|
+
remedy: `Drop ${given} for a remote run. For a local owned emulator, drop --remote and unset android.remote with \`stim settings unset android.remote --scope <workspace|repo|committed>\`.`
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function systemImageRefusal({ slot, flag, resolved, origin = null, physical, remoteBackend, listImages }) {
|
|
39
|
+
if (slot && slot !== "default" && remoteBackend) return {
|
|
40
|
+
code: "STIM_BAD_ARG",
|
|
41
|
+
message: "Named slots currently support local simulators and physical devices.",
|
|
42
|
+
remedy: "Use the default slot for a remote session."
|
|
43
|
+
};
|
|
44
|
+
if (typeof flag === "string" && flag.trim() === "") return {
|
|
45
|
+
code: "STIM_BAD_ARG",
|
|
46
|
+
message: "--system-image was given an empty id.",
|
|
47
|
+
remedy: "Pass `--system-image <id>` with an sdkmanager package id, e.g. \"system-images;android-36;google_apis;arm64-v8a\"."
|
|
48
|
+
};
|
|
49
|
+
if (physical || remoteBackend) return null;
|
|
50
|
+
if (!resolved) return null;
|
|
51
|
+
let images;
|
|
52
|
+
try {
|
|
53
|
+
images = listImages();
|
|
54
|
+
} catch (error) {
|
|
55
|
+
return {
|
|
56
|
+
code: NO_DEVICE,
|
|
57
|
+
message: `Could not read the installed Android system images: ${error?.message || error}`,
|
|
58
|
+
remedy: "Check that ANDROID_HOME points at a readable SDK, then try again."
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const refusal = unknownAndroidSystemImageRefusal(resolved, images);
|
|
62
|
+
if (!refusal) return null;
|
|
63
|
+
const { message, remedy } = layerNote(refusal, "android.systemImage", flag, origin);
|
|
64
|
+
return {
|
|
65
|
+
code: "STIM_BAD_ARG",
|
|
66
|
+
message,
|
|
67
|
+
remedy
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function resolveDeviceProfile(flag, settings) {
|
|
71
|
+
const fromFlag = typeof flag === "string" && flag.trim() !== "" ? flag.trim() : null;
|
|
72
|
+
const android = settings?.["android"];
|
|
73
|
+
const raw = android && typeof android === "object" && !Array.isArray(android) ? android["deviceProfile"] : void 0;
|
|
74
|
+
return fromFlag || (typeof raw === "string" && raw.trim() !== "" ? raw.trim() : null);
|
|
75
|
+
}
|
|
76
|
+
function deviceProfileRefusal({ flag, resolved, origin = null, physical, remoteBackend, listProfiles }) {
|
|
77
|
+
if (typeof flag === "string" && flag.trim() === "") return {
|
|
78
|
+
code: "STIM_BAD_ARG",
|
|
79
|
+
message: "--device-profile was given an empty id.",
|
|
80
|
+
remedy: "Pass `--device-profile <id>` with an id `avdmanager list device -c` prints, e.g. \"pixel_fold\"."
|
|
81
|
+
};
|
|
82
|
+
if (physical || remoteBackend || !resolved) return null;
|
|
83
|
+
let profiles;
|
|
84
|
+
try {
|
|
85
|
+
profiles = listProfiles();
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return {
|
|
88
|
+
code: NO_DEVICE,
|
|
89
|
+
message: `Could not list the Android hardware profiles with avdmanager: ${error?.message || error}`,
|
|
90
|
+
remedy: "Check that JAVA_HOME and ANDROID_HOME are set and the SDK command-line tools are installed, then try again."
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const refusal = unknownAndroidDeviceProfileRefusal(resolved, profiles);
|
|
94
|
+
if (!refusal) return null;
|
|
95
|
+
const { message, remedy } = layerNote(refusal, "android.deviceProfile", flag, origin);
|
|
96
|
+
return {
|
|
97
|
+
code: "STIM_BAD_ARG",
|
|
98
|
+
message,
|
|
99
|
+
remedy
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function foldableImageRefusal({ profile, image, avdName, images, supportsFold }) {
|
|
103
|
+
if (!profileNeedsFoldFeature(profile) || !image || supportsFold(image)) return null;
|
|
104
|
+
const compatible = pickDefaultSystemImage(images().filter((candidate) => supportsFold(candidate.pkg)))?.pkg;
|
|
105
|
+
const message = `${avdName ? `This workspace's emulator ${avdName} uses device profile ${profile} on ${image}` : `Device profile ${profile} with system image ${image}`}, which the emulator refuses to boot: ${profile} needs a system image with foldable support (SupportPixelFold in its advancedFeatures.ini).`;
|
|
106
|
+
if (!compatible) return {
|
|
107
|
+
code: "STIM_BAD_ARG",
|
|
108
|
+
message,
|
|
109
|
+
remedy: `Install an image with foldable support, e.g. \`sdkmanager "system-images;android-36;google_apis;${hostSystemImageArch()}"\`, then pass it with \`--system-image\`, or pick another \`--device-profile\`.`
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
code: "STIM_BAD_ARG",
|
|
113
|
+
message,
|
|
114
|
+
remedy: avdName ? `Pass \`--system-image "${compatible}"\`: it replaces ${avdName} if that emulator never finished a boot. Otherwise add \`--slot <name>\` to create the foldable beside it.` : `Pass \`--system-image "${compatible}"\` (or set android.systemImage to it), or pick another \`--device-profile\`.`
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function isReleaseVariant(variant) {
|
|
118
|
+
return typeof variant === "string" && /release$/i.test(variant.trim());
|
|
119
|
+
}
|
|
120
|
+
const NO_FINGERPRINT = "STIM_NO_FINGERPRINT";
|
|
121
|
+
const NO_DEVICE = "STIM_NO_DEVICE";
|
|
122
|
+
const INSTALL_FAILED = "STIM_INSTALL_FAILED";
|
|
123
|
+
const LAUNCH_FAILED = "STIM_LAUNCH_FAILED";
|
|
124
|
+
function findAapt(home = androidHome(), { readDir = readdirSync, exists = existsSync } = {}) {
|
|
125
|
+
const found = findBuildTool(["aapt", "aapt2"], {
|
|
126
|
+
home,
|
|
127
|
+
readDir,
|
|
128
|
+
exists
|
|
129
|
+
});
|
|
130
|
+
return found ? {
|
|
131
|
+
path: found.path,
|
|
132
|
+
tool: found.tool,
|
|
133
|
+
version: found.version
|
|
134
|
+
} : null;
|
|
135
|
+
}
|
|
136
|
+
function dumpApkManifest(apkPath, { exec = null, aapt = null } = {}) {
|
|
137
|
+
if (typeof apkPath !== "string" || apkPath.trim() === "") return null;
|
|
138
|
+
const tool = aapt || findAapt();
|
|
139
|
+
if (!tool) return null;
|
|
140
|
+
const e = exec || getExecutor();
|
|
141
|
+
const args = tool.tool === "aapt2" ? [
|
|
142
|
+
"dump",
|
|
143
|
+
"xmltree",
|
|
144
|
+
"--file",
|
|
145
|
+
"AndroidManifest.xml",
|
|
146
|
+
apkPath
|
|
147
|
+
] : [
|
|
148
|
+
"dump",
|
|
149
|
+
"xmltree",
|
|
150
|
+
apkPath,
|
|
151
|
+
"AndroidManifest.xml"
|
|
152
|
+
];
|
|
153
|
+
try {
|
|
154
|
+
const out = e.runFile(tool.path, args);
|
|
155
|
+
return typeof out === "string" && out.includes("E: manifest") ? out : null;
|
|
156
|
+
} catch {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function parseXmltree(text) {
|
|
161
|
+
const root = {
|
|
162
|
+
tag: "#root",
|
|
163
|
+
attrs: {},
|
|
164
|
+
children: [],
|
|
165
|
+
indent: -1
|
|
166
|
+
};
|
|
167
|
+
const stack = [root];
|
|
168
|
+
for (const raw of String(text ?? "").split("\n")) {
|
|
169
|
+
const indent = raw.search(/\S/);
|
|
170
|
+
if (indent < 0) continue;
|
|
171
|
+
const line = raw.trim();
|
|
172
|
+
const element = /^E: ([\w.:-]+)/.exec(line);
|
|
173
|
+
if (element) {
|
|
174
|
+
while (stack.length > 1 && stack[stack.length - 1].indent >= indent) stack.pop();
|
|
175
|
+
const node = {
|
|
176
|
+
tag: element[1],
|
|
177
|
+
attrs: {},
|
|
178
|
+
children: [],
|
|
179
|
+
indent
|
|
180
|
+
};
|
|
181
|
+
stack[stack.length - 1].children.push(node);
|
|
182
|
+
stack.push(node);
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const attr = /^A: ([^(=]+?)(?:\(0x[0-9a-f]+\))?=(.*)$/.exec(line);
|
|
186
|
+
if (attr && stack.length > 1) {
|
|
187
|
+
const name = attr[1].replace(/^http:\/\/schemas\.android\.com\/apk\/res\/android:/, "android:");
|
|
188
|
+
const value = /^"((?:[^"\\]|\\.)*)"/.exec(attr[2]);
|
|
189
|
+
stack[stack.length - 1].attrs[name] = value ? value[1] : null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return root;
|
|
193
|
+
}
|
|
194
|
+
function eachNode(node, fn) {
|
|
195
|
+
fn(node);
|
|
196
|
+
for (const child of node.children) eachNode(child, fn);
|
|
197
|
+
}
|
|
198
|
+
function apkPackage(text) {
|
|
199
|
+
const pkg = parseXmltree(text).children.find((c) => c.tag === "manifest")?.attrs["package"];
|
|
200
|
+
return typeof pkg === "string" && pkg.trim() ? pkg.trim() : null;
|
|
201
|
+
}
|
|
202
|
+
function apkDevClientFacts(text) {
|
|
203
|
+
const root = parseXmltree(text);
|
|
204
|
+
const facts = {
|
|
205
|
+
devClient: false,
|
|
206
|
+
schemes: []
|
|
207
|
+
};
|
|
208
|
+
let launchable = null;
|
|
209
|
+
eachNode(root, (node) => {
|
|
210
|
+
const name = node.attrs["android:name"];
|
|
211
|
+
if (typeof name === "string" && name.startsWith("expo.modules.devlauncher")) facts.devClient = true;
|
|
212
|
+
if (node.tag !== "activity" && node.tag !== "activity-alias") return;
|
|
213
|
+
const filters = node.children.filter((c) => c.tag === "intent-filter");
|
|
214
|
+
if (!filters.some((f) => f.children.some((c) => c.tag === "action" && c.attrs["android:name"] === "android.intent.action.MAIN")) || launchable) return;
|
|
215
|
+
launchable = node;
|
|
216
|
+
for (const filter of filters) for (const data of filter.children) {
|
|
217
|
+
if (data.tag !== "data") continue;
|
|
218
|
+
const scheme = data.attrs["android:scheme"];
|
|
219
|
+
if (typeof scheme === "string" && scheme.trim()) facts.schemes.push(scheme.trim());
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
return facts;
|
|
223
|
+
}
|
|
224
|
+
function androidDevClientScheme(root, apkPath, { exec = null, dump = dumpApkManifest, aapt = null } = {}) {
|
|
225
|
+
const text = dump(apkPath, {
|
|
226
|
+
exec,
|
|
227
|
+
aapt
|
|
228
|
+
});
|
|
229
|
+
if (text) {
|
|
230
|
+
const facts = apkDevClientFacts(text);
|
|
231
|
+
if (!facts.devClient) return void 0;
|
|
232
|
+
const scheme = pickDevClientScheme(facts.schemes);
|
|
233
|
+
if (scheme) return scheme;
|
|
234
|
+
}
|
|
235
|
+
return devClientScheme(root, null);
|
|
236
|
+
}
|
|
237
|
+
function noDeviceDiagnostic({ reason, logFile, remedy, localEmulator = true, readLog = readEmulatorLogTail }) {
|
|
238
|
+
const text = localEmulator ? readLog(logFile) : "";
|
|
239
|
+
const logPath = text.trim() ? logFile : null;
|
|
240
|
+
const found = extractEmulatorFailure(text);
|
|
241
|
+
const diskRemedy = localEmulator ? emulatorDiskSpaceRemedy([reason, ...found]) : null;
|
|
242
|
+
if (found.length === 0) return {
|
|
243
|
+
message: reason,
|
|
244
|
+
remedy: diskRemedy ?? remedy,
|
|
245
|
+
lines: [],
|
|
246
|
+
logPath
|
|
247
|
+
};
|
|
248
|
+
return {
|
|
249
|
+
message: `${reason} The emulator reported: ${found[0]}`,
|
|
250
|
+
remedy: diskRemedy ?? emulatorFailureRemedy(found),
|
|
251
|
+
lines: found.slice(1),
|
|
252
|
+
logPath
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function readEmulatorLogTail(file) {
|
|
256
|
+
try {
|
|
257
|
+
return readFileSync(file, "utf-8").split("\n").slice(-400).join("\n");
|
|
258
|
+
} catch {
|
|
259
|
+
return "";
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function displayPath(root, path) {
|
|
263
|
+
const rel = relative(root, path);
|
|
264
|
+
return rel && !rel.startsWith("..") ? rel : path;
|
|
265
|
+
}
|
|
266
|
+
async function pooledAndroidDevice({ root, selectPool, listDevices, isEmulatorDevice, deviceModel, waitSeconds, noWait, now, warn }) {
|
|
267
|
+
const isEmulator = memoizeEmulatorProbe(isEmulatorDevice);
|
|
268
|
+
const pooled = await selectPool({
|
|
269
|
+
root,
|
|
270
|
+
platform: PLATFORM,
|
|
271
|
+
idLabel: "serial",
|
|
272
|
+
list: () => androidPoolCandidates(listDevices(), isEmulator).map((entry) => ({ id: entry.serial })),
|
|
273
|
+
noCandidates: () => {
|
|
274
|
+
const resolved = androidPoolNoCandidatesRefusal(listDevices(), isEmulator);
|
|
275
|
+
return {
|
|
276
|
+
message: resolved.error,
|
|
277
|
+
remedy: resolved.remedy
|
|
278
|
+
};
|
|
279
|
+
},
|
|
280
|
+
waitSeconds,
|
|
281
|
+
noWait,
|
|
282
|
+
now,
|
|
283
|
+
warn
|
|
284
|
+
});
|
|
285
|
+
if (pooled.status === "refused") {
|
|
286
|
+
const { code, message, remedy, lease } = pooled.refusal;
|
|
287
|
+
return {
|
|
288
|
+
code,
|
|
289
|
+
message,
|
|
290
|
+
remedy,
|
|
291
|
+
extra: lease === null ? {} : { lease }
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
return { device: {
|
|
295
|
+
serial: pooled.candidate.id,
|
|
296
|
+
deviceName: deviceModel(pooled.candidate.id) ?? pooled.candidate.id,
|
|
297
|
+
owned: false
|
|
298
|
+
} };
|
|
299
|
+
}
|
|
300
|
+
function androidBuildOptions({ release, physical, device, variant, deviceAbi, compiler, buildProfile, targetAbiOnly = true }) {
|
|
301
|
+
let abi = null;
|
|
302
|
+
if (targetAbiOnly && !release && physical && device.serial) abi = deviceAbi(device.serial);
|
|
303
|
+
if (targetAbiOnly && !release && !physical) abi = androidSystemImageAbi(device.systemImage);
|
|
304
|
+
const runOptions = {};
|
|
305
|
+
if (variant) runOptions.variant = variant;
|
|
306
|
+
if (abi) runOptions.abi = abi;
|
|
307
|
+
if (compiler) runOptions.compiler = compiler;
|
|
308
|
+
if (buildProfile) runOptions.buildProfile = buildProfile;
|
|
309
|
+
return {
|
|
310
|
+
abi,
|
|
311
|
+
runOptions,
|
|
312
|
+
remoteRunOptions: Object.keys(runOptions).length === 0 ? null : runOptions
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
//#endregion
|
|
316
|
+
export { resolveSystemImage as C, resolveDeviceProfile as S, systemImageRefusal as T, isReleaseVariant as _, PLATFORM as a, pooledAndroidDevice as b, androidSystemImageSetting as c, apkPackage as d, deviceProfileRefusal as f, foldableImageRefusal as g, findAapt as h, NO_FINGERPRINT as i, androidVariantSetting as l, dumpApkManifest as m, LAUNCH_FAILED as n, androidBuildOptions as o, displayPath as p, NO_DEVICE as r, androidDevClientScheme as s, INSTALL_FAILED as t, apkDevClientFacts as u, noDeviceDiagnostic as v, resolveVariant as w, remoteAvdFlagRefusal as x, parseXmltree as y };
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { h as shortUdid, l as phaseLine } from "./command-output-DnJMdEY-.mjs";
|
|
2
|
+
import { x as workspaceLogsDir } from "./workspace-state-B8-aJ1_5.mjs";
|
|
3
|
+
import { k as parseIosSimulatorApp } from "./ios-BaInn3sW.mjs";
|
|
4
|
+
import { x as describeDiagnostic } from "./toolchain-DkUflduf.mjs";
|
|
5
|
+
import { c as unknownIosDeviceTypeRefusal, l as unknownIosRuntimeRefusal, r as layerNote } from "./device-capacity-BHwxNBlu.mjs";
|
|
6
|
+
import { l as parseDeviceWait } from "./device-lease-run-CqjShqWW.mjs";
|
|
7
|
+
import { t as IosDeviceMismatchError } from "./device-ios-BadmeL2V.mjs";
|
|
8
|
+
import { basename, join } from "node:path";
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
function buildLogFile(root) {
|
|
11
|
+
return join(workspaceLogsDir(root), `build-ios.ndjson`);
|
|
12
|
+
}
|
|
13
|
+
const MAX_PRINTED_DIAGNOSTICS = 6;
|
|
14
|
+
function deviceLabel(device, udid) {
|
|
15
|
+
const name = device?.deviceName || device?.name || null;
|
|
16
|
+
return name ? `${name} (${shortUdid(udid)})` : shortUdid(udid);
|
|
17
|
+
}
|
|
18
|
+
function deviceShortName(device, udid) {
|
|
19
|
+
return device?.deviceName || device?.name || shortUdid(udid);
|
|
20
|
+
}
|
|
21
|
+
function appNameFromPath(appPath) {
|
|
22
|
+
if (typeof appPath !== "string" || appPath.trim() === "") return null;
|
|
23
|
+
const name = basename(appPath).replace(/\.app$/i, "");
|
|
24
|
+
return name === "" ? null : name;
|
|
25
|
+
}
|
|
26
|
+
function iosConfigurationSetting(settings) {
|
|
27
|
+
const ios = settings?.["ios"];
|
|
28
|
+
if (!ios || typeof ios !== "object" || Array.isArray(ios)) return null;
|
|
29
|
+
const raw = ios["configuration"];
|
|
30
|
+
return typeof raw === "string" && raw.trim() !== "" ? raw.trim() : null;
|
|
31
|
+
}
|
|
32
|
+
function resolveConfiguration(flag, settings) {
|
|
33
|
+
return (typeof flag === "string" && flag.trim() !== "" ? flag.trim() : null) || iosConfigurationSetting(settings);
|
|
34
|
+
}
|
|
35
|
+
function iosStringSetting(settings, key) {
|
|
36
|
+
const ios = settings?.["ios"];
|
|
37
|
+
if (!ios || typeof ios !== "object" || Array.isArray(ios)) return null;
|
|
38
|
+
const raw = ios[key];
|
|
39
|
+
return typeof raw === "string" && raw.trim() !== "" ? raw.trim() : null;
|
|
40
|
+
}
|
|
41
|
+
function resolveDeviceType(flag, settings) {
|
|
42
|
+
return (typeof flag === "string" && flag.trim() !== "" ? flag.trim() : null) || iosStringSetting(settings, "deviceType");
|
|
43
|
+
}
|
|
44
|
+
function resolveRuntime(flag, settings) {
|
|
45
|
+
return (typeof flag === "string" && flag.trim() !== "" ? flag.trim() : null) || iosStringSetting(settings, "runtime");
|
|
46
|
+
}
|
|
47
|
+
function resolveSimulatorAppFlag(flag, physical, remoteBackend) {
|
|
48
|
+
if (flag === void 0) return {};
|
|
49
|
+
let simulatorApp;
|
|
50
|
+
try {
|
|
51
|
+
simulatorApp = parseIosSimulatorApp(flag, "--simulator-app");
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return { refusal: {
|
|
54
|
+
code: "STIM_BAD_ARG",
|
|
55
|
+
message: error.message
|
|
56
|
+
} };
|
|
57
|
+
}
|
|
58
|
+
if (physical || remoteBackend) return { refusal: {
|
|
59
|
+
code: "STIM_BAD_ARG",
|
|
60
|
+
message: "--simulator-app only applies to a local owned iOS simulator.",
|
|
61
|
+
remedy: "Drop --simulator-app when using a physical or remote device."
|
|
62
|
+
} };
|
|
63
|
+
return { simulatorApp };
|
|
64
|
+
}
|
|
65
|
+
function deviceModelRefusal({ slot, deviceTypeFlag, runtimeFlag, deviceType, runtime, deviceTypeOrigin = null, runtimeOrigin = null, physical, remoteBackend, hosted = false, listRuntimes }) {
|
|
66
|
+
if (slot && slot !== "default" && remoteBackend) return {
|
|
67
|
+
code: "STIM_BAD_ARG",
|
|
68
|
+
message: "Named slots currently support local simulators and physical devices.",
|
|
69
|
+
remedy: "Use the default slot for a remote session."
|
|
70
|
+
};
|
|
71
|
+
if (typeof deviceTypeFlag === "string" && deviceTypeFlag.trim() === "") return {
|
|
72
|
+
code: "STIM_BAD_ARG",
|
|
73
|
+
message: "--device-type was given an empty name.",
|
|
74
|
+
remedy: "Pass `--device-type <name>` with a model `xcrun simctl list devicetypes` names, e.g. \"iPad Pro 13-inch (M5)\"."
|
|
75
|
+
};
|
|
76
|
+
if (typeof runtimeFlag === "string" && runtimeFlag.trim() === "") return {
|
|
77
|
+
code: "STIM_BAD_ARG",
|
|
78
|
+
message: "--runtime was given an empty version.",
|
|
79
|
+
remedy: "Pass `--runtime <version>` with a runtime `xcrun simctl list runtimes` reports, e.g. \"18.5\"."
|
|
80
|
+
};
|
|
81
|
+
if (remoteBackend) {
|
|
82
|
+
const eas = remoteBackend === "eas";
|
|
83
|
+
const given = [!eas && deviceTypeFlag && "--device-type", runtimeFlag && "--runtime"].filter(Boolean).join(" and ");
|
|
84
|
+
if (given) return {
|
|
85
|
+
code: "STIM_BAD_ARG",
|
|
86
|
+
message: `${given} ${given.includes(" and ") ? "apply" : "applies"} only to a local owned iOS simulator; the ${remoteBackend} remote backend chooses its own ${eas ? "iOS runtime" : "device"}.`,
|
|
87
|
+
remedy: `Drop ${given} for a remote run. For a local owned simulator, drop --remote and unset ios.remote with \`stim settings unset ios.remote --scope <workspace|repo|committed>\`.`
|
|
88
|
+
};
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
if (physical || hosted) return null;
|
|
92
|
+
if (!deviceType && !runtime) return null;
|
|
93
|
+
let runtimes;
|
|
94
|
+
try {
|
|
95
|
+
runtimes = listRuntimes();
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
code: "STIM_NO_DEVICE",
|
|
99
|
+
message: `Could not read the installed simulator runtimes: ${error?.message || error}`,
|
|
100
|
+
remedy: "Run `stim doctor` to check the simulator toolchain, then try again."
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const runtimeRefusal = unknownIosRuntimeRefusal(runtime, runtimes);
|
|
104
|
+
if (runtimeRefusal) {
|
|
105
|
+
const { message, remedy } = layerNote(runtimeRefusal, "ios.runtime", runtimeFlag, runtimeOrigin);
|
|
106
|
+
return {
|
|
107
|
+
code: "STIM_BAD_ARG",
|
|
108
|
+
message,
|
|
109
|
+
remedy
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const deviceTypeRefusal = unknownIosDeviceTypeRefusal(deviceType, runtimes, runtime);
|
|
113
|
+
if (deviceTypeRefusal) {
|
|
114
|
+
const { message, remedy } = layerNote(deviceTypeRefusal, "ios.deviceType", deviceTypeFlag, deviceTypeOrigin);
|
|
115
|
+
return {
|
|
116
|
+
code: "STIM_BAD_ARG",
|
|
117
|
+
message,
|
|
118
|
+
remedy
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
function ownedSimFailure(error) {
|
|
124
|
+
return {
|
|
125
|
+
code: "STIM_NO_DEVICE",
|
|
126
|
+
message: `Could not ensure an owned iOS simulator: ${error?.message || error}`,
|
|
127
|
+
remedy: error instanceof IosDeviceMismatchError ? error.remedy : "Run `stim doctor` to check the simulator toolchain, then try again."
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function isReleaseConfiguration(configuration) {
|
|
131
|
+
return typeof configuration === "string" && configuration.trim() !== "" && configuration.trim().toLowerCase() !== "debug";
|
|
132
|
+
}
|
|
133
|
+
function simulatorBuildArch({ physical, remoteArch, hostArch, configuration }) {
|
|
134
|
+
if (physical) return null;
|
|
135
|
+
if (remoteArch) return remoteArch;
|
|
136
|
+
return isReleaseConfiguration(configuration) ? null : hostArch;
|
|
137
|
+
}
|
|
138
|
+
function iosProviderRunOptions(configuration, arch) {
|
|
139
|
+
if (arch) return {
|
|
140
|
+
configuration: configuration || "Debug",
|
|
141
|
+
arch
|
|
142
|
+
};
|
|
143
|
+
return configuration ? { configuration } : null;
|
|
144
|
+
}
|
|
145
|
+
function podAction(podState, verdict) {
|
|
146
|
+
if (verdict?.stale) return {
|
|
147
|
+
install: true,
|
|
148
|
+
reason: verdict.reason
|
|
149
|
+
};
|
|
150
|
+
if (verdict?.noPods && podState?.hasPodfile) return {
|
|
151
|
+
install: true,
|
|
152
|
+
reason: "ios/Podfile exists but no pods are installed"
|
|
153
|
+
};
|
|
154
|
+
return { install: false };
|
|
155
|
+
}
|
|
156
|
+
function xcodeFailureReport(result, logPath) {
|
|
157
|
+
const diagnostics = result.diagnostics;
|
|
158
|
+
const code = result.exitCode;
|
|
159
|
+
const how = code === null ? "" : ` (exit code ${code})`;
|
|
160
|
+
return {
|
|
161
|
+
message: diagnostics.length ? `\`xcodebuild\` failed${how} with ${diagnostics.length} diagnostic${diagnostics.length === 1 ? "" : "s"}.` : `\`xcodebuild\` failed${how} with no recognizable diagnostic.`,
|
|
162
|
+
remedy: diagnostics.find((d) => d?.remedy)?.remedy || `See ${logPath} for the transcript.`
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function printDiagnostics(note, result) {
|
|
166
|
+
const diagnostics = result.diagnostics;
|
|
167
|
+
const shown = diagnostics.slice(0, MAX_PRINTED_DIAGNOSTICS);
|
|
168
|
+
for (const diagnostic of shown) note(chalk.red(phaseLine("error", describeDiagnostic(diagnostic))));
|
|
169
|
+
const hidden = diagnostics.length - shown.length + result.truncated;
|
|
170
|
+
if (hidden > 0) note(chalk.dim(phaseLine("error", `... and ${hidden} more diagnostic${hidden === 1 ? "" : "s"} in the log`)));
|
|
171
|
+
if (diagnostics.length === 0) {
|
|
172
|
+
note(chalk.red(phaseLine("error", "xcodebuild failed with no recognizable diagnostic; last lines:")));
|
|
173
|
+
for (const line of result.tail.slice(-5)) note(chalk.dim(phaseLine("", line)));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function resolveIosWait(opts, physical) {
|
|
177
|
+
const noWait = opts.wait === false;
|
|
178
|
+
const waitFlagged = opts.wait !== void 0;
|
|
179
|
+
if (opts.waitConflict) return { failure: {
|
|
180
|
+
code: "STIM_BAD_ARG",
|
|
181
|
+
message: "--wait and --no-wait ask for opposite things.",
|
|
182
|
+
remedy: "Pass `--wait <seconds>` to wait for the lease, or `--no-wait` to install without one."
|
|
183
|
+
} };
|
|
184
|
+
if (waitFlagged && !physical) return { failure: {
|
|
185
|
+
code: "STIM_BAD_ARG",
|
|
186
|
+
message: "--wait and --no-wait only apply to a `--device` run.",
|
|
187
|
+
remedy: "This workspace owns its simulator, so nothing contends for it. Drop the flag, or pass `--device`."
|
|
188
|
+
} };
|
|
189
|
+
const waitParsed = parseDeviceWait(noWait ? void 0 : opts.wait);
|
|
190
|
+
if ("error" in waitParsed) return { failure: {
|
|
191
|
+
code: "STIM_BAD_ARG",
|
|
192
|
+
message: waitParsed.error,
|
|
193
|
+
remedy: "Pass a whole number of seconds, e.g. --wait 90. `--wait 0` refuses a leased device at once."
|
|
194
|
+
} };
|
|
195
|
+
return {
|
|
196
|
+
waitSeconds: waitParsed.seconds,
|
|
197
|
+
noWait
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
//#endregion
|
|
201
|
+
export { simulatorBuildArch as _, deviceShortName as a, isReleaseConfiguration as c, printDiagnostics as d, resolveConfiguration as f, resolveSimulatorAppFlag as g, resolveRuntime as h, deviceModelRefusal as i, ownedSimFailure as l, resolveIosWait as m, buildLogFile as n, iosConfigurationSetting as o, resolveDeviceType as p, deviceLabel as r, iosProviderRunOptions as s, appNameFromPath as t, podAction as u, xcodeFailureReport as v };
|