stim 1.5.0 → 1.7.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/{android-DJWiTBkz.mjs → android-DWssqHQ8.mjs} +165 -661
- package/dist/{android-sobvO9ia.mjs → android-Da-G_o3n.mjs} +646 -548
- package/dist/{android-BW8i_YxU.mjs → android-DeYdjjBP.mjs} +6 -2
- package/dist/{android-cas-CSS8gjR7.mjs → android-cas-SWIjzeuL.mjs} +54 -18
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/{app-install--PAocWvq.mjs → app-install-DJg7bVv-.mjs} +36 -10
- package/dist/build-lock-CgtsB6TV.mjs +604 -0
- package/dist/{build-slots-CuPszJDu.mjs → build-slots-C-oAHRT1.mjs} +2 -2
- package/dist/{cache-manifest-uoOKhgUD.mjs → cache-manifest-CYJi8-Hx.mjs} +2 -2
- package/dist/cache-manifest.d.mts +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +14 -14
- package/dist/collector-run.d.mts +2 -0
- package/dist/collector-run.mjs +7 -7
- package/dist/{command-output-BuIb_ZOI.mjs → command-output-B3ycpsYv.mjs} +2 -2
- package/dist/{config-DMP7L7H6.mjs → config-B7iyKWkL.mjs} +56 -16
- package/dist/{dependency-state-CTL8A9p3.mjs → dependency-state-D0M7oKA7.mjs} +2 -2
- package/dist/{deps-BAGOnrc7.mjs → deps-oCXVNEqQ.mjs} +6 -6
- package/dist/detached-entry-Bpo6ZY_I.mjs +65 -0
- package/dist/{dev-client-BoifdqkU.mjs → dev-client-DDUkWgJL.mjs} +12 -12
- package/dist/{device-BUw4JBuH.mjs → device-CBSaC6BU.mjs} +7 -7
- package/dist/{device-DvKJ454A.mjs → device-CLeDp-KH.mjs} +17 -15
- package/dist/{device-lease-r7yEQ1R8.mjs → device-lease-Ffz_M5t0.mjs} +3 -3
- package/dist/{device-pool-DU4FQKp5.mjs → device-pool-DNSHL5z8.mjs} +4 -4
- package/dist/{device-remote-BTUqbl0i.mjs → device-remote-BprxZp-m.mjs} +11 -11
- package/dist/{doctor-Di_B26uh.mjs → doctor-CTAx9gMu.mjs} +90 -46
- package/dist/{error-diagnostics-CTePWAzW.mjs → error-diagnostics-D1Kaf-eT.mjs} +23 -17
- package/dist/{exec-CyylIdq9.mjs → exec-B29XNuhP.mjs} +14 -2
- package/dist/{gc-C20dWw_8.mjs → gc-CX0KRfLG.mjs} +17 -16
- package/dist/{guide-sAnoty2y.mjs → guide-CPmAG9me.mjs} +61 -22
- package/dist/{guide-status-BF6RsJJp.mjs → guide-status-Craq9z0t.mjs} +3 -3
- package/dist/{ios-BdpkncL6.mjs → ios-BRXYSxSc.mjs} +34 -37
- package/dist/{ios-device-DJOi9FR5.mjs → ios-device-CDbvn5H2.mjs} +2 -2
- package/dist/{ios-device-D3pzTKQE.mjs → ios-device-CFXA46ez.mjs} +1 -1
- package/dist/{ios-Deh5js5V.mjs → ios-lEJ5pKsq.mjs} +3 -3
- package/dist/{logs-BfQdIhiF.mjs → logs-CakdBTtm.mjs} +6 -6
- package/dist/{logs-query-Cdp5aaCH.mjs → logs-query-BGL-Pl12.mjs} +1 -1
- package/dist/metro-C7bcJ0uo.mjs +233 -0
- package/dist/{named-ports-DH9SXd0f.mjs → named-ports-DzMOlmaX.mjs} +57 -42
- package/dist/{ownership-CD_XnpDu.mjs → ownership-Cp52QAK1.mjs} +3 -3
- package/dist/{ownership-CVY9cqCr.mjs → ownership-D5vkdm8H.mjs} +13 -13
- package/dist/{ports-A6uTJSPj.mjs → ports-BIbJaKNW.mjs} +3 -3
- package/dist/{process-output-C7IlIzd7.mjs → process-output-Dl5uKE03.mjs} +1 -1
- package/dist/{project-B_SDt4ip.mjs → project-DDZWf_16.mjs} +3 -3
- package/dist/{reclaim-C_rB25f4.mjs → reclaim-D614jI6_.mjs} +11 -11
- package/dist/{reload-CYBJbJfI.mjs → reload-ChW46VDb.mjs} +9 -9
- package/dist/{server-bare-H3pAhbMs.mjs → server-bare-BQkyxa_b.mjs} +1 -1
- package/dist/{server-expo-Ds8_mfng.mjs → server-expo-BVAA1OqJ.mjs} +23 -11
- package/dist/server-expo-YDDG3eP7.mjs +2 -0
- package/dist/{settings-kO2ZqIKy.mjs → settings-BXXorVM2.mjs} +8 -5
- package/dist/{slot-launch-BpHiHH6A.mjs → slot-launch-DbLvyrup.mjs} +4 -4
- package/dist/{start-DiEfqEWk.mjs → start-TTVILlUi.mjs} +111 -38
- package/dist/{state-CnWzvCWP.mjs → state-DZobzxLW.mjs} +2 -2
- package/dist/{stats-Fo9ACIv7.mjs → stats-BYcZ6n1h.mjs} +1 -1
- package/dist/{stats-DHrO0frH.mjs → stats-CLg5RuDS.mjs} +4 -4
- package/dist/{status-J5LAXpag.mjs → status-DUNy_HZs.mjs} +14 -15
- package/dist/{stop-CM1fejKW.mjs → stop-CnUpnFT5.mjs} +2 -2
- package/dist/{stop-0jJNahwN.mjs → stop-ZrfODZ51.mjs} +13 -13
- package/dist/supervisor-run.mjs +7 -5
- package/dist/{teardown-CAVcWeRD.mjs → teardown-5J5UXz2P.mjs} +14 -17
- package/dist/{workspace-process-lock-Bz19_R9R.mjs → workspace-process-lock-BYfZz_S-.mjs} +1 -1
- package/dist/{workspace-state-WVwWw_hB.mjs → workspace-state-BT5E3SA2.mjs} +3 -3
- package/dist/{worktree-CeUKDAQw.mjs → worktree-BfE4lzHK.mjs} +21 -16
- package/dist/{worktree-DJnBbQZ9.mjs → worktree-FG_ZKKdb.mjs} +13 -9
- package/dist/{xcode-BqDeRkpT.mjs → xcode-B6YaWeg0.mjs} +92 -17
- package/package.json +12 -8
- package/shim/android-optimizations.gradle +6 -0
- package/dist/metro-ato6ef3J.mjs +0 -99
- package/dist/ports-BZprTJRa.mjs +0 -90
- package/dist/server-expo-CSwUVYOa.mjs +0 -2
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { g as loadConfig, l as getConcurrencyLimits, o as configCorruptRepair } from "./config-
|
|
3
|
-
import { l as sharedBuildCache, m as workspaceDerivedData } from "./workspace-state-
|
|
4
|
-
import { C as filesystemDevice, E as temporaryRoot, a as dirtyFingerprintFiles, d as listWorktrees, f as locallyKnownUpstream, g as repoRoot, s as gitCommonDir, v as resolveSourceCheckout, w as makeTemporaryDirectory } from "./worktree-
|
|
5
|
-
import { a as findProjectRoot, i as detectIsExpo, t as appProjectProblem } from "./project-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { h as
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
1
|
+
import { t as getExecutor } from "./exec-B29XNuhP.mjs";
|
|
2
|
+
import { g as loadConfig, l as getConcurrencyLimits, o as configCorruptRepair } from "./config-B7iyKWkL.mjs";
|
|
3
|
+
import { l as sharedBuildCache, m as workspaceDerivedData } from "./workspace-state-BT5E3SA2.mjs";
|
|
4
|
+
import { C as filesystemDevice, E as temporaryRoot, a as dirtyFingerprintFiles, d as listWorktrees, f as locallyKnownUpstream, g as repoRoot, s as gitCommonDir, v as resolveSourceCheckout, w as makeTemporaryDirectory } from "./worktree-FG_ZKKdb.mjs";
|
|
5
|
+
import { a as findProjectRoot, i as detectIsExpo, t as appProjectProblem } from "./project-DDZWf_16.mjs";
|
|
6
|
+
import { A as resolveSettings, E as remoteAndroidSetting, I as unknownSettingKeys, M as settingOrigin, N as settingShapeErrors, O as remoteIosSetting, P as settingsLayers, U as resolveOptimizations, V as compilerCacheFallbackMessage, a as SETTING_SHAPE_REMEDY, i as SETTINGS_WITH_RESOLVE_TIME_FALLBACK, n as PATH_SETTINGS, v as iosSimSlimProfileSetting, w as projectOptimizations, y as mergeSettingsLayers } from "./settings-BXXorVM2.mjs";
|
|
7
|
+
import { S as listAdbDevices, x as hostSystemImageArch } from "./android-DWssqHQ8.mjs";
|
|
8
|
+
import { d as quotedPath, l as phaseLine, u as plural } from "./command-output-B3ycpsYv.mjs";
|
|
9
|
+
import { m as fingerprintProject, r as listBuildLocks, u as diffFingerprintSources } from "./build-lock-CgtsB6TV.mjs";
|
|
10
|
+
import { S as resolveEasCliBin, a as POOL_SETTING_REMEDY, b as ownerFromConfig, h as checkEasAuth$1, l as parkedMaxSetting, x as providerFromConfig } from "./teardown-5J5UXz2P.mjs";
|
|
11
|
+
import { E as readHostMemoryPressure, T as hostMemoryPressureAdvice, u as listAllIosSims } from "./ios-lEJ5pKsq.mjs";
|
|
12
|
+
import { n as listBuildSlots } from "./build-slots-C-oAHRT1.mjs";
|
|
13
|
+
import { a as liveOwnedDeviceCount, d as simslimIsOnPath } from "./device-CLeDp-KH.mjs";
|
|
14
|
+
import { d as projectCmakeLauncher, g as androidPathRoomRemedy, h as androidPathRoomMessage, i as apkOutputsDir, m as androidPathRoom, r as resolveAndroidCompilerCache, t as readAndroidCasToolchain } from "./android-cas-SWIjzeuL.mjs";
|
|
15
|
+
import { h as podInstallCommand, i as ccacheEnabled, o as detectXcodeMajor } from "./xcode-B6YaWeg0.mjs";
|
|
16
|
+
import { i as inspectStimVersions, n as recordDoctorRun, r as compareStimVersions } from "./guide-status-Craq9z0t.mjs";
|
|
17
|
+
import { n as hasInstalledDependencies, r as installedNpmTreeIsValid, t as dependencyState } from "./dependency-state-D0M7oKA7.mjs";
|
|
17
18
|
import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync, rmSync } from "node:fs";
|
|
18
19
|
import { InvalidArgumentError } from "commander";
|
|
19
20
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
20
21
|
import { existsSync as existsSync$1, lstatSync as lstatSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, realpathSync as realpathSync$1, renameSync as renameSync$1, rmSync as rmSync$1, writeFileSync as writeFileSync$1 } from "fs";
|
|
21
22
|
import { homedir } from "os";
|
|
22
|
-
import { dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, relative as relative$1, resolve as resolve$1 } from "path";
|
|
23
|
+
import { dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, relative as relative$1, resolve as resolve$1, sep as sep$1 } from "path";
|
|
23
24
|
import * as expoFingerprint from "@expo/fingerprint";
|
|
24
25
|
import chalk from "chalk";
|
|
25
|
-
//#region src/sandbox.ts
|
|
26
|
+
//#region src/diagnostics/sandbox.ts
|
|
26
27
|
/**
|
|
27
28
|
* What a sandboxed harness has to permit for Stim to work: its state
|
|
28
29
|
* directory, the XPC service simctl talks to, and the port adb's server binds.
|
|
@@ -111,8 +112,12 @@ function nested(source, ...keys) {
|
|
|
111
112
|
}
|
|
112
113
|
/** Whether an allowWrite entry covers the Stim home, including as a parent. */
|
|
113
114
|
function covers(entry, target, home) {
|
|
114
|
-
const
|
|
115
|
-
|
|
115
|
+
const posix = (value) => {
|
|
116
|
+
const expanded = expandHome(value, home);
|
|
117
|
+
return sep$1 === "/" ? expanded : expanded.replaceAll(sep$1, "/");
|
|
118
|
+
};
|
|
119
|
+
const e = posix(entry.replace(/\/+\*+$/, "").replace(/\/+$/, ""));
|
|
120
|
+
const t = posix(target.replace(/\/+$/, ""));
|
|
116
121
|
return e === t || t.startsWith(`${e}/`);
|
|
117
122
|
}
|
|
118
123
|
/**
|
|
@@ -224,8 +229,8 @@ function sandboxFinding(settingsRoot, { env = process.env, home = homedir(), sti
|
|
|
224
229
|
};
|
|
225
230
|
}
|
|
226
231
|
//#endregion
|
|
227
|
-
//#region src/doctor-storage.ts
|
|
228
|
-
function checkStorageLayout(projectRoot, { platform, device = filesystemDevice, stagingRoot = temporaryRoot } = {}) {
|
|
232
|
+
//#region src/diagnostics/doctor-storage.ts
|
|
233
|
+
function checkStorageLayout(projectRoot, { platform, host = process.platform, device = filesystemDevice, stagingRoot = temporaryRoot } = {}) {
|
|
229
234
|
const findings = [];
|
|
230
235
|
const temporaryFix = "Unset STIM_TMPDIR / machine tempDir to select same-volume staging automatically, or point the override at a writable directory on the relevant volume outside Git working trees.";
|
|
231
236
|
const check = (operation, paths, fix) => {
|
|
@@ -244,7 +249,7 @@ function checkStorageLayout(projectRoot, { platform, device = filesystemDevice,
|
|
|
244
249
|
const cache = sharedBuildCache();
|
|
245
250
|
check("Cached app/APK staging", [cache, stagingRoot(join(cache, "artifact.app"))], temporaryFix);
|
|
246
251
|
const cacheFix = "Place STIM_BUILD_CACHE / machine caches.buildCache on the build-output volume, or accept the full-copy cost of keeping the cache on a separate volume.";
|
|
247
|
-
if (platform === "ios" || platform !== "android" && existsSync(join(projectRoot, "ios"))) {
|
|
252
|
+
if ((platform === "ios" || platform !== "android" && existsSync(join(projectRoot, "ios"))) && host === "darwin") {
|
|
248
253
|
const output = join(workspaceDerivedData(projectRoot), "Build", "Products");
|
|
249
254
|
check("iOS build-cache storage", [output, cache], cacheFix);
|
|
250
255
|
check("iOS device app staging", [output, stagingRoot(join(output, "artifact.app"))], temporaryFix);
|
|
@@ -261,7 +266,7 @@ function checkStorageLayout(projectRoot, { platform, device = filesystemDevice,
|
|
|
261
266
|
return findings;
|
|
262
267
|
}
|
|
263
268
|
//#endregion
|
|
264
|
-
//#region src/doctor-ios-architectures.ts
|
|
269
|
+
//#region src/diagnostics/doctor-ios-architectures.ts
|
|
265
270
|
const COMPILED_PRODUCTS = /* @__PURE__ */ new Set([
|
|
266
271
|
"com.apple.product-type.application",
|
|
267
272
|
"com.apple.product-type.application.on-demand-install-capable",
|
|
@@ -397,7 +402,7 @@ function inspectIosDebugArchitectures(projectRoot) {
|
|
|
397
402
|
return findings;
|
|
398
403
|
}
|
|
399
404
|
//#endregion
|
|
400
|
-
//#region src/doctor-cxx.ts
|
|
405
|
+
//#region src/diagnostics/doctor-cxx.ts
|
|
401
406
|
function parseCmakeCacheLauncher(source) {
|
|
402
407
|
if (typeof source !== "string") return null;
|
|
403
408
|
return /^CMAKE_CXX_COMPILER_LAUNCHER(?::[A-Z]+)?=(.*)$/m.exec(source)?.[1]?.trim() || null;
|
|
@@ -474,7 +479,7 @@ function repairCxxLauncherState(root) {
|
|
|
474
479
|
refused: []
|
|
475
480
|
};
|
|
476
481
|
if (selectedCompilerCache(root) !== "ccache") return result;
|
|
477
|
-
if (!getExecutor().
|
|
482
|
+
if (!getExecutor().findExecutable("ccache")) return result;
|
|
478
483
|
const appOverrides = declaredLauncher(join(root, "android", "app"));
|
|
479
484
|
const targets = readCxxLauncherStates(root).filter(({ launcher }) => {
|
|
480
485
|
if (!launcher) return true;
|
|
@@ -530,7 +535,7 @@ function repairCxxLauncherState(root) {
|
|
|
530
535
|
return result;
|
|
531
536
|
}
|
|
532
537
|
//#endregion
|
|
533
|
-
//#region src/doctor-config.ts
|
|
538
|
+
//#region src/diagnostics/doctor-config.ts
|
|
534
539
|
function readMachineSettings(context) {
|
|
535
540
|
try {
|
|
536
541
|
const layers = settingsLayers(context);
|
|
@@ -639,7 +644,7 @@ function missingPath(value, projectRoot, exists, trim = false) {
|
|
|
639
644
|
return opened === opened.trim() ? path : JSON.stringify(path);
|
|
640
645
|
}
|
|
641
646
|
//#endregion
|
|
642
|
-
//#region src/doctor.ts
|
|
647
|
+
//#region src/diagnostics/doctor.ts
|
|
643
648
|
function finding(level, title, detail, fix) {
|
|
644
649
|
return {
|
|
645
650
|
level,
|
|
@@ -768,7 +773,7 @@ function seedFindings(mainRoot, upstream) {
|
|
|
768
773
|
if (defaultBranch !== null && defaultBranch !== branch) findings.push(finding("note", `The source checkout is on ${branch}, not the default branch ${defaultBranch}`, `Every worktree warmed from here carries ${branch}'s dependencies. \`stim worktree warm --refresh\` warns and continues; it never switches a branch under another checkout.`, `Run \`git -C ${quotedRoot} checkout ${defaultBranch}\`.`));
|
|
769
774
|
return findings;
|
|
770
775
|
}
|
|
771
|
-
function checkMainCheckout(projectRoot, { npmTreeValid, brokenPods = void 0, upstream = void 0, linkedWorktrees = void 0, platform } = {}) {
|
|
776
|
+
function checkMainCheckout(projectRoot, { npmTreeValid, brokenPods = void 0, upstream = void 0, linkedWorktrees = void 0, platform, localIos = platform !== "android" } = {}) {
|
|
772
777
|
const mainRoot = mainCheckoutProjectRoot(projectRoot);
|
|
773
778
|
const findings = [];
|
|
774
779
|
const dependencies = dependencyState(mainRoot);
|
|
@@ -783,7 +788,7 @@ function checkMainCheckout(projectRoot, { npmTreeValid, brokenPods = void 0, ups
|
|
|
783
788
|
const podfileLock = join$1(mainRoot, "ios", "Podfile.lock");
|
|
784
789
|
const podManifest = join$1(mainRoot, "ios", "Pods", "Manifest.lock");
|
|
785
790
|
const podsRoot = join$1(mainRoot, "ios", "Pods");
|
|
786
|
-
if (
|
|
791
|
+
if (localIos && existsSync$1(podfileLock)) {
|
|
787
792
|
let podsState = null;
|
|
788
793
|
if (!existsSync$1(podManifest)) podsState = "missing";
|
|
789
794
|
else try {
|
|
@@ -803,7 +808,7 @@ function checkMainCheckout(projectRoot, { npmTreeValid, brokenPods = void 0, ups
|
|
|
803
808
|
findings.push(finding("cost", "The source checkout CocoaPods state has broken links", `${broken.length} symlink${broken.length === 1 ? "" : "s"} under ios/Pods point to missing files. Worktrees copy these broken links and can fail during compilation. First: ${broken[0]}.`, `Run \`${podCommand}\` before creating native worktrees.`));
|
|
804
809
|
}
|
|
805
810
|
}
|
|
806
|
-
const coldPlatforms = [
|
|
811
|
+
const coldPlatforms = [localIos && existsSync$1(join$1(mainRoot, "ios")) && !hasIosWarmOutput(mainRoot) ? "iOS" : null, platform !== "ios" && existsSync$1(join$1(mainRoot, "android")) && !existsSync$1(join$1(mainRoot, "android", "build")) && !existsSync$1(join$1(mainRoot, "android", "app", "build")) ? "Android" : null].filter((coldPlatform) => coldPlatform !== null);
|
|
807
812
|
if (coldPlatforms.length) findings.push(finding("note", `The source checkout has no ${coldPlatforms.join(" or ")} warm build output`, "The shared Stim artifact or compilation cache can still be warm. Building the source checkout once gives later native worktrees the strongest warm starting point.", `When more native worktrees are expected, run \`stim start\`, \`stim ${coldPlatforms[0] === "iOS" ? "ios" : "android"}\`, and \`stim stop\` from ${mainRoot}.`));
|
|
808
813
|
if (linkedWorktrees === void 0 ? hasLinkedWorktree(projectRoot) : linkedWorktrees) findings.push(...seedFindings(mainRoot, upstream === void 0 ? locallyKnownUpstream(mainRoot) : upstream));
|
|
809
814
|
return findings;
|
|
@@ -846,7 +851,7 @@ function checkCcacheConflict(podfileSource, podfileProperties) {
|
|
|
846
851
|
}
|
|
847
852
|
function checkCcacheInstalled(onPath) {
|
|
848
853
|
if (onPath) return null;
|
|
849
|
-
return finding("cost", "ccache is not on PATH, so Android C++ recompiles in every worktree", "Stim resolves the launcher with
|
|
854
|
+
return finding("cost", "ccache is not on PATH, so Android C++ recompiles in every worktree", "Stim resolves the launcher with a PATH lookup for `ccache` -- the same lookup the build itself uses -- and found nothing, so it passes no CMAKE_C_COMPILER_LAUNCHER / CMAKE_CXX_COMPILER_LAUNCHER to Gradle and every AGP CMake task compiles without one. Those tasks are uncacheable by Gradle, so not one C++ object crosses a worktree. Measured on trailhead (arm64, fresh worktree): 49.6s without the launcher against 34.2s with it.", "brew install ccache, then delete android/app/.cxx and node_modules/**/android/.cxx once so CMake reconfigures with the launcher. The shell that runs Stim must have the install location on PATH -- agent shells often lack /opt/homebrew/bin.");
|
|
850
855
|
}
|
|
851
856
|
function launcherPath(launcher) {
|
|
852
857
|
const command = launcher?.split(";")[0]?.trim();
|
|
@@ -868,7 +873,7 @@ function checkCxxCompilerLauncher({ states, ccacheOnPath, launcherExists = exist
|
|
|
868
873
|
}
|
|
869
874
|
function ccacheIsOnPath() {
|
|
870
875
|
try {
|
|
871
|
-
return Boolean(getExecutor().
|
|
876
|
+
return Boolean(getExecutor().findExecutable("ccache"));
|
|
872
877
|
} catch {
|
|
873
878
|
return false;
|
|
874
879
|
}
|
|
@@ -915,7 +920,25 @@ function checkSimSlim({ configured = false, profileError = null, onPath = false
|
|
|
915
920
|
if (onPath) return null;
|
|
916
921
|
return finding("cost", "A SimSlim profile is configured, but SimSlim is not installed", "`stim ios` needs the `simslim` command to apply the profile to its owned simulator.", "brew install mobai-app/tap/simslim");
|
|
917
922
|
}
|
|
918
|
-
function
|
|
923
|
+
function checkIosHost(platform, host) {
|
|
924
|
+
if (platform !== "ios" || host === "darwin") return null;
|
|
925
|
+
return finding("note", `iOS runs through EAS on this ${host} host`, "Xcode, CocoaPods and simctl exist only on macOS, so `stim ios` cannot build or boot a simulator here. `stim ios --remote eas --eas-profile <simulator profile>` downloads a finished EAS development build and runs it on an EAS Simulator session driven through agent-device; Metro stays on this machine behind a tunnel.", "Install eas-cli and agent-device, then run `stim start --remote` and `stim ios --remote eas --eas-profile <profile>`. Read `stim guide metro` for the remote device backends.");
|
|
926
|
+
}
|
|
927
|
+
function checkXcodeEnvLineEndings(projectRoot, platform, host) {
|
|
928
|
+
if (platform === "android" || host !== "win32") return null;
|
|
929
|
+
const xcodeEnv = join$1(projectRoot, "ios", ".xcode.env");
|
|
930
|
+
if (!existsSync$1(xcodeEnv)) return null;
|
|
931
|
+
let content;
|
|
932
|
+
try {
|
|
933
|
+
content = readFileSync$1(xcodeEnv, "utf-8");
|
|
934
|
+
} catch {
|
|
935
|
+
return null;
|
|
936
|
+
}
|
|
937
|
+
if (!content.includes("\r")) return null;
|
|
938
|
+
return finding("cost", "ios/.xcode.env has CRLF line endings", "An EAS build uploads the working-tree bytes of ios/.xcode.env, and Xcode sources that file with sh on the build worker, where each carriage return becomes part of the line and the build fails with `: command not found`. On Windows the usual cause is core.autocrlf=true rewriting the file at checkout.", "Run `git config core.autocrlf input` then `git checkout -- ios/.xcode.env`, or add `ios/.xcode.env text eol=lf` to .gitattributes and check the file out again.");
|
|
939
|
+
}
|
|
940
|
+
function runDoctor(projectRoot, { readFile = readFileSync$1, xcodeMajor = null, easAuth = checkEasAuth$1, concurrency = getConcurrencyLimits, liveDevices = null, activeBuilds = null, remoteEnv = process.env, lookupAgentDevice = null, lookupEasCli = null, lookupSimSlim = null, memoryPressure = readHostMemoryPressure, lookupCcache = null, platform, host = process.platform } = {}) {
|
|
941
|
+
const localIos = platform !== "android" && host === "darwin";
|
|
919
942
|
const read = (rel) => {
|
|
920
943
|
const p = join$1(projectRoot, rel);
|
|
921
944
|
if (!existsSync$1(p)) return null;
|
|
@@ -982,12 +1005,12 @@ function runDoctor(projectRoot, { readFile = readFileSync$1, xcodeMajor = null,
|
|
|
982
1005
|
}
|
|
983
1006
|
let simslimProfile = null;
|
|
984
1007
|
let simslimProfileError = null;
|
|
985
|
-
if (
|
|
1008
|
+
if (localIos) try {
|
|
986
1009
|
simslimProfile = iosSimSlimProfileSetting(projectSettings, projectRoot);
|
|
987
1010
|
} catch (error) {
|
|
988
1011
|
simslimProfileError = String(error?.message || error);
|
|
989
1012
|
}
|
|
990
|
-
const simslimFinding =
|
|
1013
|
+
const simslimFinding = !localIos || !simslimProfile && !simslimProfileError && remoteIosSetting(projectSettings) ? null : checkSimSlim({
|
|
991
1014
|
configured: Boolean(simslimProfile),
|
|
992
1015
|
profileError: simslimProfileError,
|
|
993
1016
|
onPath: simslimProfile ? lookupSimSlim ? lookupSimSlim() : simslimIsOnPath() : false
|
|
@@ -1002,16 +1025,25 @@ function runDoctor(projectRoot, { readFile = readFileSync$1, xcodeMajor = null,
|
|
|
1002
1025
|
agentDeviceOnPath,
|
|
1003
1026
|
easCliResolvable
|
|
1004
1027
|
})).filter((remoteFinding) => remoteFinding !== null);
|
|
1005
|
-
const memoryAdvice =
|
|
1028
|
+
const memoryAdvice = localIos && !remoteIosSetting(projectSettings) ? hostMemoryPressureAdvice(memoryPressure()) : null;
|
|
1006
1029
|
return [
|
|
1007
1030
|
checkAppProject(projectRoot),
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
...
|
|
1031
|
+
checkIosHost(platform, host),
|
|
1032
|
+
checkXcodeEnvLineEndings(projectRoot, platform, host),
|
|
1033
|
+
...checkMainCheckout(projectRoot, {
|
|
1034
|
+
platform,
|
|
1035
|
+
localIos
|
|
1036
|
+
}),
|
|
1037
|
+
...localIos ? inspectIosDebugArchitectures(mainCheckoutProjectRoot(projectRoot)) : [],
|
|
1038
|
+
...checkStorageLayout(projectRoot, {
|
|
1039
|
+
platform,
|
|
1040
|
+
host
|
|
1041
|
+
}),
|
|
1011
1042
|
optimizations?.metroSharedCache ? checkMetroCache(metroConfig) : null,
|
|
1012
|
-
|
|
1013
|
-
|
|
1043
|
+
localIos && optimizations?.ios.compilationCache ? checkCompilationCache(podfile, xcodeMajor) : null,
|
|
1044
|
+
localIos && optimizations?.ios.compilationCache ? checkCcacheConflict(podfile, podfileProperties) : null,
|
|
1014
1045
|
...platform === "ios" || optimizations?.android.compilerCache !== "ccache" ? [] : androidCcacheFindings(projectRoot, platform, lookupCcache),
|
|
1046
|
+
checkAndroidPathRoom(projectRoot, platform, host),
|
|
1015
1047
|
remoteBuildCache ? checkBuildCacheProvider(appConfig, sdkMajor, isExpo, dynamicConfig) : null,
|
|
1016
1048
|
easFinding,
|
|
1017
1049
|
concurrencyFinding,
|
|
@@ -1028,6 +1060,17 @@ function runDoctor(projectRoot, { readFile = readFileSync$1, xcodeMajor = null,
|
|
|
1028
1060
|
})
|
|
1029
1061
|
].filter((f) => Boolean(f));
|
|
1030
1062
|
}
|
|
1063
|
+
function checkAndroidPathRoom(projectRoot, platform, host, hostArch = process.arch) {
|
|
1064
|
+
const room = platform === "ios" ? null : androidPathRoom(projectRoot, {
|
|
1065
|
+
abi: hostSystemImageArch(hostArch),
|
|
1066
|
+
platform: host
|
|
1067
|
+
});
|
|
1068
|
+
if (!room) return null;
|
|
1069
|
+
return {
|
|
1070
|
+
code: "android-path-room",
|
|
1071
|
+
...finding("cost", "The project path leaves no room for Android native object paths", `${androidPathRoomMessage(room)} \`stim android\` refuses to build here with STIM_PATH_TOO_LONG, because Gradle would fail deep inside ninja instead.`, androidPathRoomRemedy(room))
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1031
1074
|
function androidCcacheFindings(projectRoot, platform, lookupCcache) {
|
|
1032
1075
|
if (platform !== "android" && !existsSync$1(join$1(projectRoot, "android"))) return [];
|
|
1033
1076
|
const onPath = lookupCcache ? lookupCcache() : ccacheIsOnPath();
|
|
@@ -1050,7 +1093,7 @@ function checkAppProject(projectRoot) {
|
|
|
1050
1093
|
}
|
|
1051
1094
|
function agentDeviceIsOnPath() {
|
|
1052
1095
|
try {
|
|
1053
|
-
return Boolean(getExecutor().
|
|
1096
|
+
return Boolean(getExecutor().findExecutable("agent-device"));
|
|
1054
1097
|
} catch {
|
|
1055
1098
|
return true;
|
|
1056
1099
|
}
|
|
@@ -1338,7 +1381,7 @@ function applySandboxFix(root, env = process.env) {
|
|
|
1338
1381
|
console.error(chalk.green(`${result.status === "created" ? "Wrote" : "Updated"} ${target}`));
|
|
1339
1382
|
console.error(chalk.dim("Added writes to Stim's state directory, the simulator XPC service, and local port binding. Claude Code reads project settings from the directory a session starts in, so this file only counts for sessions rooted there. Restart the session for it to take effect."));
|
|
1340
1383
|
}
|
|
1341
|
-
function doctorCommand(program, version, inspectVersions = inspectStimVersions) {
|
|
1384
|
+
function doctorCommand(program, version, inspectVersions = inspectStimVersions, host = process.platform) {
|
|
1342
1385
|
program.command("doctor").description("Inspect the source checkout and report project state that can make native worktrees slow or invalid. The checkout is left untouched unless --fix is passed; --platform filters native findings. Each run is recorded in Stim state so guide can say when doctor is due.").option("--json", "print the findings as JSON").option("--platform <platform>", "report shared findings plus only this native platform: ios or android", parseDoctorPlatform).option("--fix", "repair the sandbox allowance when the report names it, and stale Android .cxx configurations in this checkout. Stop native builds first. Generated CMake output must be ignored and untracked; custom launcher settings and source files are preserved.").action(async (opts) => {
|
|
1343
1386
|
const root = findProjectRoot(process.cwd());
|
|
1344
1387
|
if (!root) {
|
|
@@ -1360,8 +1403,9 @@ function doctorCommand(program, version, inspectVersions = inspectStimVersions)
|
|
|
1360
1403
|
}
|
|
1361
1404
|
const stim = await inspectVersions(version);
|
|
1362
1405
|
const findings = runDoctor(root, {
|
|
1363
|
-
xcodeMajor: opts.platform
|
|
1364
|
-
platform: opts.platform
|
|
1406
|
+
xcodeMajor: opts.platform !== "android" && host === "darwin" ? detectXcodeMajor() : null,
|
|
1407
|
+
platform: opts.platform,
|
|
1408
|
+
host
|
|
1365
1409
|
});
|
|
1366
1410
|
const parity = await detectFingerprintParity(root, { platform: opts.platform });
|
|
1367
1411
|
if (parity) findings.push(parity);
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { D as withDirLock, F as
|
|
3
|
-
import { r as readWorkspaceState } from "./workspace-state-
|
|
4
|
-
import { d as readWorkspaceLaunches } from "./state-
|
|
5
|
-
import { n as deviceConsoleLevel } from "./ios-device-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { a as parseLease, n as fileLeaseIo, t as deviceLeasePath } from "./device-lease-
|
|
11
|
-
import { l as readLogRecords, t as attachExpoErrorContext } from "./logs-query-
|
|
1
|
+
import { t as getExecutor } from "./exec-B29XNuhP.mjs";
|
|
2
|
+
import { D as withDirLock, F as deviceSlotKey, I as deviceSlotPlatforms, f as getProject } from "./config-B7iyKWkL.mjs";
|
|
3
|
+
import { r as readWorkspaceState } from "./workspace-state-BT5E3SA2.mjs";
|
|
4
|
+
import { d as readWorkspaceLaunches } from "./state-DZobzxLW.mjs";
|
|
5
|
+
import { n as deviceConsoleLevel } from "./ios-device-CFXA46ez.mjs";
|
|
6
|
+
import { a as resolveProjectMetro } from "./metro-C7bcJ0uo.mjs";
|
|
7
|
+
import { r as androidHome, s as androidToolCwd } from "./android-DWssqHQ8.mjs";
|
|
8
|
+
import { n as parseLogcatLine, t as androidClockOffset } from "./android-DeYdjjBP.mjs";
|
|
9
|
+
import { _ as launchErrorPreview } from "./command-output-B3ycpsYv.mjs";
|
|
10
|
+
import { a as parseLease, n as fileLeaseIo, t as deviceLeasePath } from "./device-lease-Ffz_M5t0.mjs";
|
|
11
|
+
import { l as readLogRecords, t as attachExpoErrorContext } from "./logs-query-BGL-Pl12.mjs";
|
|
12
12
|
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
13
13
|
import { createHash, randomUUID } from "node:crypto";
|
|
14
14
|
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
15
15
|
import { homedir } from "node:os";
|
|
16
|
-
//#region src/diagnostic-store.ts
|
|
16
|
+
//#region src/diagnostics/diagnostic-store.ts
|
|
17
17
|
/** Publishes an immutable diagnostic snapshot atomically; existing evidence wins. */
|
|
18
18
|
function writeDiagnosticOnce(path, content) {
|
|
19
19
|
mkdirSync(dirname(path), { recursive: true });
|
|
@@ -34,7 +34,7 @@ function writeDiagnosticOnce(path, content) {
|
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
//#endregion
|
|
37
|
-
//#region src/native-crash.ts
|
|
37
|
+
//#region src/diagnostics/native-crash.ts
|
|
38
38
|
const IOS_CRASH_REPORT_RETRY = "iOS crash reports can take about a minute or longer to appear. Run `stim logs --errors` again for the native stack.";
|
|
39
39
|
/** Accepts only a report for this app, simulator and launch window. */
|
|
40
40
|
function parseIosCrash(text, target) {
|
|
@@ -329,7 +329,10 @@ function captureNativeCrashes(target, logsDir) {
|
|
|
329
329
|
"time,epoch",
|
|
330
330
|
"-t",
|
|
331
331
|
"2000"
|
|
332
|
-
], {
|
|
332
|
+
], {
|
|
333
|
+
timeoutMs: 3e3,
|
|
334
|
+
cwd: androidToolCwd()
|
|
335
|
+
});
|
|
333
336
|
const deadline = Date.now() + 4e3;
|
|
334
337
|
if (text) records = parseAndroidCrashes(text, target, offset).map((record) => symbolicateAndroid(record, target.root, deadline));
|
|
335
338
|
}
|
|
@@ -384,7 +387,10 @@ function captureWorkspaceCrashes(root, logsDir) {
|
|
|
384
387
|
"emu",
|
|
385
388
|
"avd",
|
|
386
389
|
"name"
|
|
387
|
-
], {
|
|
390
|
+
], {
|
|
391
|
+
timeoutMs: 2e3,
|
|
392
|
+
cwd: androidToolCwd()
|
|
393
|
+
})?.split("\n")[0]?.trim() !== configured.avdName) continue;
|
|
388
394
|
}
|
|
389
395
|
}
|
|
390
396
|
captureNativeCrashes({
|
|
@@ -402,7 +408,7 @@ function captureWorkspaceCrashes(root, logsDir) {
|
|
|
402
408
|
}
|
|
403
409
|
}
|
|
404
410
|
//#endregion
|
|
405
|
-
//#region src/error-symbolication.ts
|
|
411
|
+
//#region src/diagnostics/error-symbolication.ts
|
|
406
412
|
const LOCATION = /https?:\/\/[^\s)'"\\]+?:\d+:\d+/g;
|
|
407
413
|
function frameFromLocation(location) {
|
|
408
414
|
const match = /^(https?:\/\/.+):(\d+):(\d+)$/.exec(location);
|
|
@@ -490,7 +496,7 @@ async function symbolicateErrors(records, { port, timeoutMs = 2e3, request = fet
|
|
|
490
496
|
}
|
|
491
497
|
}
|
|
492
498
|
//#endregion
|
|
493
|
-
//#region src/error-diagnostics.ts
|
|
499
|
+
//#region src/diagnostics/error-diagnostics.ts
|
|
494
500
|
function key(record) {
|
|
495
501
|
return createHash("sha256").update(JSON.stringify(record)).digest("hex");
|
|
496
502
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import spawn from "cross-spawn";
|
|
3
|
+
import which from "which";
|
|
2
4
|
//#region src/exec.ts
|
|
3
5
|
const MAX_BUFFER = 67108864;
|
|
4
6
|
let active = {
|
|
@@ -38,7 +40,14 @@ let active = {
|
|
|
38
40
|
for (const key of omitEnv ?? []) delete childEnv[key];
|
|
39
41
|
opts.env = childEnv;
|
|
40
42
|
}
|
|
41
|
-
|
|
43
|
+
const result = spawn.sync(file, args, opts);
|
|
44
|
+
if (result.error) throw Object.assign(result.error, result);
|
|
45
|
+
if (result.status !== 0) {
|
|
46
|
+
const stderr = String(result.stderr ?? "");
|
|
47
|
+
const message = `Command failed: ${[file, ...args].join(" ")}${stderr ? `\n${stderr}` : ""}`;
|
|
48
|
+
throw Object.assign(new Error(message), result);
|
|
49
|
+
}
|
|
50
|
+
return String(result.stdout).trim();
|
|
42
51
|
},
|
|
43
52
|
runQuiet(cmd, opts) {
|
|
44
53
|
try {
|
|
@@ -56,6 +65,9 @@ let active = {
|
|
|
56
65
|
},
|
|
57
66
|
spawn(cmd, args = [], opts = {}) {
|
|
58
67
|
return spawn(cmd, args, opts);
|
|
68
|
+
},
|
|
69
|
+
findExecutable(name) {
|
|
70
|
+
return which.sync(name, { nothrow: true });
|
|
59
71
|
}
|
|
60
72
|
};
|
|
61
73
|
function getExecutor() {
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { A as isOnMountedVolume, C as withConfigLock, E as ownership_claim_exports,
|
|
3
|
-
import { i as registeredCaches } from "./cache-manifest-
|
|
4
|
-
import { h as workspaceDir, y as workspaceStateFile } from "./workspace-state-
|
|
5
|
-
import { g as repoRoot, s as gitCommonDir } from "./worktree-
|
|
6
|
-
import { a as findProjectRoot, i as detectIsExpo } from "./project-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
1
|
+
import { t as getExecutor } from "./exec-B29XNuhP.mjs";
|
|
2
|
+
import { A as isOnMountedVolume, C as withConfigLock, E as ownership_claim_exports, I as deviceSlotPlatforms, M as volumeRootFor, O as directorySize, R as projectDeviceSlots, f as getProject, g as loadConfig, i as clearDevice, j as listMountedVolumes, k as formatBytes, u as getConfigDir, v as removeProject } from "./config-B7iyKWkL.mjs";
|
|
3
|
+
import { i as registeredCaches } from "./cache-manifest-CYJi8-Hx.mjs";
|
|
4
|
+
import { h as workspaceDir, y as workspaceStateFile } from "./workspace-state-BT5E3SA2.mjs";
|
|
5
|
+
import { g as repoRoot, s as gitCommonDir } from "./worktree-FG_ZKKdb.mjs";
|
|
6
|
+
import { a as findProjectRoot, i as detectIsExpo } from "./project-DDZWf_16.mjs";
|
|
7
|
+
import { A as resolveSettings, N as settingShapeErrors, a as SETTING_SHAPE_REMEDY } from "./settings-BXXorVM2.mjs";
|
|
8
|
+
import { C as listAvds, O as ownedAvdDirectory, T as listOrphanedAvdDirectories } from "./android-DWssqHQ8.mjs";
|
|
9
|
+
import { m as shortUdid, o as formatLongDuration, u as plural } from "./command-output-B3ycpsYv.mjs";
|
|
10
|
+
import { r as listBuildLocks } from "./build-lock-CgtsB6TV.mjs";
|
|
11
|
+
import { S as resolveEasCliBin, a as POOL_SETTING_REMEDY, i as teardownParkedIosSim, l as parkedMaxSetting, n as teardownOwnedIosSim, r as teardownParkedAvd, s as dropParked, t as teardownOwnedAvd, u as readParked } from "./teardown-5J5UXz2P.mjs";
|
|
12
|
+
import { d as listIosDeviceTypes, g as parseRuntimeVersion, u as listAllIosSims } from "./ios-lEJ5pKsq.mjs";
|
|
13
|
+
import { i as listLeaseFiles, r as leaseIsExpired, u as removeExpiredLease } from "./device-lease-Ffz_M5t0.mjs";
|
|
14
|
+
import { n as listBuildSlots } from "./build-slots-C-oAHRT1.mjs";
|
|
15
|
+
import { C as verifyStoppedSession, S as stopSessionArgs, _ as inspectSessionForTeardown, d as withEasProjectLock, f as easMachineStateRoot, g as getSessionArgs, h as findOrphanedOwnedSessions, m as removeEasSessionClaim, p as readEasSessionLedger, u as withRemoteSessionLock, v as isDefinitiveMissingSessionError, x as parseSessionListPage, y as listOwnedSessionsArgs } from "./device-remote-BprxZp-m.mjs";
|
|
16
|
+
import { n as reclaimProject, t as describeDereferenced } from "./reclaim-D614jI6_.mjs";
|
|
16
17
|
import { InvalidArgumentError } from "commander";
|
|
17
18
|
import { existsSync, readFileSync, readdirSync, realpathSync, rmSync, statSync } from "fs";
|
|
18
19
|
import { homedir, tmpdir } from "os";
|
|
19
20
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "path";
|
|
20
21
|
import { METRO_NAMED_CACHE_LAYOUT } from "@stim-cli/core";
|
|
21
22
|
import chalk from "chalk";
|
|
22
|
-
//#region src/caches.ts
|
|
23
|
+
//#region src/cache/caches.ts
|
|
23
24
|
function xcodeDerivedDataRoot() {
|
|
24
25
|
return join(homedir(), "Library", "Developer", "Xcode", "DerivedData");
|
|
25
26
|
}
|