stim 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +4 -3
  2. package/dist/{android-CqcW1hrP.mjs → android-CT-PkXUh.mjs} +22 -19
  3. package/dist/{android-cas-BR5YJBYv.mjs → android-cas-DXorPCi_.mjs} +2 -2
  4. package/dist/{android-BqVIJoG7.mjs → android-hMj83VpN.mjs} +12 -6
  5. package/dist/{build-slots-C3-R4XQr.mjs → build-slots-C4AouyNz.mjs} +1 -1
  6. package/dist/cli.mjs +12 -12
  7. package/dist/{deps-Spz8ozgo.mjs → deps-0Yt0Inly.mjs} +1 -1
  8. package/dist/{dev-client-BjisHDB5.mjs → dev-client-VfSZNLT4.mjs} +4 -4
  9. package/dist/{device-BkiW-gkk.mjs → device-Bbv45Z9Z.mjs} +3 -3
  10. package/dist/{device-lease-BJYybF-2.mjs → device-lease-CJwK7OZr.mjs} +1 -1
  11. package/dist/{device-pool-CPbLGfrB.mjs → device-pool-CcBNTvM7.mjs} +1 -1
  12. package/dist/{device-remote-AkYCKS8U.mjs → device-remote-DAA0Zm6Z.mjs} +1 -1
  13. package/dist/{doctor-Bmv86UUW.mjs → doctor-B4EITgQB.mjs} +5 -5
  14. package/dist/{doctor-fAMXC4vl.mjs → doctor-BueDfLYG.mjs} +2 -2
  15. package/dist/{error-diagnostics-DHC31rXA.mjs → error-diagnostics-DwhNBFDU.mjs} +3 -3
  16. package/dist/{gc-GGu-8ULN.mjs → gc-BRu62v4o.mjs} +7 -7
  17. package/dist/{guide-92CPA21s.mjs → guide-D95E0u3i.mjs} +111 -61
  18. package/dist/{ios-BSXFeO5H.mjs → ios-DAju3TVy.mjs} +12 -12
  19. package/dist/{logs-DPNF4C9s.mjs → logs-CAdwW6c2.mjs} +29 -4
  20. package/dist/{logs-query-R-Cqc6Qv.mjs → logs-query-Cdp5aaCH.mjs} +1 -1
  21. package/dist/{ownership-BpCKiRlQ.mjs → ownership-DXcol4oU.mjs} +1 -1
  22. package/dist/{ownership-claim-Bf2CAfw3.mjs → ownership-claim-BtPtJVmq.mjs} +35 -21
  23. package/dist/{reclaim-iW9Cad7k.mjs → reclaim-CUmwucWG.mjs} +4 -4
  24. package/dist/{reload-DazHDSFA.mjs → reload-CWpXoOgN.mjs} +2 -2
  25. package/dist/{slot-launch-cci0xvmC.mjs → slot-launch-CZklomj6.mjs} +1 -1
  26. package/dist/{start-mObjQH2W.mjs → start-B5G4NjiA.mjs} +3 -3
  27. package/dist/{status-BxQNqu9t.mjs → status-CI9clRSb.mjs} +6 -6
  28. package/dist/{stop-CrHGcjrV.mjs → stop-CQhffpmX.mjs} +2 -2
  29. package/dist/{stop-DimGXEKY.mjs → stop-CjlgDk0a.mjs} +5 -5
  30. package/dist/{teardown-ClFp1Aax.mjs → teardown--gESs9ck.mjs} +103 -4
  31. package/dist/{workspace-process-lock-3NcQnZ0X.mjs → workspace-process-lock-IBj1Towr.mjs} +1 -1
  32. package/dist/{worktree-DxTgN1CJ.mjs → worktree-DtQGO9-s.mjs} +116 -106
  33. package/dist/{xcode-D7sAp-Zy.mjs → xcode-xnxyvJkD.mjs} +81 -44
  34. package/package.json +5 -5
@@ -6,12 +6,12 @@ import { s as ownedDeviceLabel } from "./project-fKmuIaMI.mjs";
6
6
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-C7IlIzd7.mjs";
7
7
  import { r as pidExists } from "./metro-CORqXyTL.mjs";
8
8
  import { a as formatElapsed, l as phaseLine } from "./command-output-8wHMEde0.mjs";
9
- import { f as releaseClaim, h as tryAcquireClaim, i as claimRemoveCommand, l as markClaimChildPending, n as ClaimRefusedError, p as setClaimChild, u as processGroupAlive } from "./ownership-claim-Bf2CAfw3.mjs";
10
- import { A as pickDefaultSystemImage, D as ownedAvdName, E as ownedAvdMatchesConfiguration, L as waitForBoot, N as resolveOwnedAvdSerial, O as ownedAvdSystemImage, b as listAvds, c as avdPoolConfiguration, d as configureNewOwnedAvd, f as createOwnedAvd, o as assertOwnedAvdStopped, u as bootAndroidEmulator, v as getAvdNameForSerial, w as nextConsolePort, x as listInstalledSystemImages, y as listAdbDevices } from "./android-BqVIJoG7.mjs";
9
+ import { c as markClaimChildPending, d as releaseClaim, f as setClaimChild, i as claimRemoveCommand, l as processGroupAlive, m as tryAcquireClaim, t as ClaimRefusedError } from "./ownership-claim-BtPtJVmq.mjs";
10
+ import { A as pickDefaultSystemImage, D as ownedAvdName, E as ownedAvdMatchesConfiguration, L as waitForBoot, N as resolveOwnedAvdSerial, O as ownedAvdSystemImage, b as listAvds, c as avdPoolConfiguration, d as configureNewOwnedAvd, f as createOwnedAvd, o as assertOwnedAvdStopped, u as bootAndroidEmulator, v as getAvdNameForSerial, w as nextConsolePort, x as listInstalledSystemImages, y as listAdbDevices } from "./android-hMj83VpN.mjs";
11
11
  import { U as resolveOptimizations, l as androidDataPartitionSizeGbSetting, o as androidAvdConfigSetting, v as iosSimSlimProfileSetting } from "./settings-DEJf6_kJ.mjs";
12
12
  import { t as cleanLine } from "./server-expo-DizT4OMk.mjs";
13
- import { c as parkedMaxSetting, i as teardownParkedIosSim, l as readParked, o as adoptParked, r as teardownParkedAvd, s as dropParked, t as teardownOwnedAvd, u as selectParked } from "./teardown-ClFp1Aax.mjs";
14
- import { t as withWorkspaceProcessLock } from "./workspace-process-lock-3NcQnZ0X.mjs";
13
+ import { c as parkedMaxSetting, i as teardownParkedIosSim, l as readParked, o as adoptParked, r as teardownParkedAvd, s as dropParked, t as teardownOwnedAvd, u as selectParked } from "./teardown--gESs9ck.mjs";
14
+ import { t as withWorkspaceProcessLock } from "./workspace-process-lock-IBj1Towr.mjs";
15
15
  import { E as readHostMemoryPressure, T as hostMemoryPressureAdvice, _ as renameIosSim, b as resolveIosCreation, c as iosRuntimeMatches, d as listIosDeviceTypes, g as parseRuntimeVersion, i as createOwnedIosSim, l as iosSimulatorFailureAdvice, m as ownedSimName, n as bootIosSim, u as listAllIosSims, v as resetIosKeychain, x as resolveOwnedIosSim, y as resetIosPrivacy } from "./ios-Deh5js5V.mjs";
16
16
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
17
17
  import { createHash, randomUUID } from "node:crypto";
@@ -460,13 +460,14 @@ function findOtherProjectOwningAvd(avdName, projectPath, selectedSlot = "default
460
460
  for (const [path, proj] of Object.entries(cfg?.projects || {})) if (projectDeviceSlots(proj).some(({ slot, platforms }) => (path !== projectPath || slot !== selectedSlot) && platforms.android?.avdName?.toLowerCase() === avdName.toLowerCase())) return path;
461
461
  return null;
462
462
  }
463
- var AvdRecoveryError = class extends Error {
463
+ var AvdBootError = class extends Error {
464
464
  remedy;
465
465
  constructor(message, remedy, cause) {
466
466
  super(message, { cause });
467
467
  this.remedy = remedy;
468
468
  }
469
469
  };
470
+ var AvdRecoveryError = class extends AvdBootError {};
470
471
  async function ensureOwnedAndroidDevice({ record, projectPath, slot, settingsRoot, label, settings, flags, note, out, logFile, alive, configureAvd, teardownAvd }) {
471
472
  const avdConfig = androidAvdConfigSetting(settings, settingsRoot);
472
473
  const configuration = avdPoolConfiguration(androidDataPartitionSizeGbSetting(settings), avdConfig);
@@ -699,10 +700,17 @@ async function bootOwnedAvdOnFreshPort({ avdName, metadata, projectPath, slot, d
699
700
  });
700
701
  const serial = `emulator-${claim.consolePort}`;
701
702
  try {
703
+ reportAndroidMemoryPressure(out);
702
704
  const pid = bootAndroidEmulator(avdName, claim.consolePort, { logFile });
703
705
  out(chalk.dim(phaseLine("device", `waiting for ${serial} to finish booting`)));
704
- const result = await waitForBoot(serial, 12e4, { aborted: emulatorGone(pid, alive) });
705
- if (!result.ok) throw new Error(`${bootFailurePrefix(serial, result.exited, 12e4)} Diagnostic: ${JSON.stringify(result.diagnostic)}`);
706
+ const result = await waitForAndroidBoot({
707
+ serial,
708
+ timeoutMs: 12e4,
709
+ pid,
710
+ alive,
711
+ out
712
+ });
713
+ if (result.failed) throw new AvdBootError(result.reason, result.remedy);
706
714
  const running = getAvdNameForSerial(serial);
707
715
  if (running && running !== avdName) throw new Error(`${serial} is running AVD ${running}, not this workspace's owned AVD ${avdName}; refusing to use it.`);
708
716
  return {
@@ -714,12 +722,54 @@ async function bootOwnedAvdOnFreshPort({ avdName, metadata, projectPath, slot, d
714
722
  throw error;
715
723
  }
716
724
  }
717
- function emulatorGone(pid, alive) {
718
- if (!pid) return () => false;
719
- return () => !alive(pid);
725
+ function reportAndroidMemoryPressure(out) {
726
+ const pressure = readHostMemoryPressure();
727
+ if (pressure === "warning" || pressure === "critical") out(chalk.dim(phaseLine("memory", `macOS reports ${pressure} host memory pressure; emulator boot may be slow. Free memory with \`stim stop\` only in workspaces you own; ask before closing other apps or devices.`)));
720
728
  }
721
- function bootFailurePrefix(serial, exited, timeoutMs) {
722
- return exited ? `The emulator process for ${serial} exited before the device finished booting.` : `Emulator ${serial} did not finish booting within ${Math.round(timeoutMs / 1e3)}s.`;
729
+ function androidBootRemedy(pressure) {
730
+ let count = null;
731
+ try {
732
+ count = liveOwnedDeviceCount({
733
+ sims: process.platform === "darwin" ? listAllIosSims({ timeoutMs: 2e3 }) : [],
734
+ adbEmulators: listAdbDevices({ timeoutMs: 2e3 }).emulators,
735
+ config: loadConfig()
736
+ });
737
+ } catch {}
738
+ const observation = pressure === "warning" || pressure === "critical" ? `macOS reports ${pressure} host memory pressure. ` : "";
739
+ const devices = count ? `${count} Stim-owned ${count === 1 ? "device is" : "devices are"} running. ` : "";
740
+ if (observation || devices) return `${observation}${devices}Stop an unneeded device with \`stim stop\` only in a workspace you own, then run \`stim android\` again; ask before closing other apps or devices. These observations do not establish the cause of the timeout or an OOM crash.`;
741
+ return "Inspect the emulator log and run `stim doctor` to check JAVA_HOME, ANDROID_HOME, and installed system images, then run `stim android` again.";
742
+ }
743
+ async function waitForAndroidBoot({ serial, timeoutMs, pid = null, alive = pidExists, out }) {
744
+ const aborted = () => pid !== null && !alive(pid);
745
+ const wait = (windowMs) => waitForBoot(serial, windowMs, {
746
+ aborted,
747
+ commandTimeoutMs: 5e3
748
+ });
749
+ let result = await wait(timeoutMs);
750
+ if (result.ok) return {
751
+ ok: true,
752
+ serial
753
+ };
754
+ let pressure = readHostMemoryPressure();
755
+ let elapsedMs = timeoutMs;
756
+ if (!result.exited && pid !== null && !aborted() && (pressure === "warning" || pressure === "critical")) {
757
+ const extensionMs = 24e4;
758
+ out(chalk.dim(phaseLine("memory", `macOS reports ${pressure} host memory pressure; retrying the boot wait once for the same live emulator ${serial} (up to ${extensionMs / 1e3}s more).`)));
759
+ result = await wait(extensionMs);
760
+ if (result.ok) return {
761
+ ok: true,
762
+ serial
763
+ };
764
+ elapsedMs += extensionMs;
765
+ pressure = readHostMemoryPressure();
766
+ }
767
+ const exited = result.exited || aborted();
768
+ return {
769
+ failed: true,
770
+ reason: `${exited ? `The emulator process for ${serial} exited before the device finished booting.` : `Emulator ${serial} did not finish booting within ${Math.round(elapsedMs / 1e3)}s.`} Diagnostic: ${JSON.stringify(result.diagnostic)}`,
771
+ remedy: exited ? "Inspect the emulator log for the process exit, fix what it reports, then run `stim android` again." : androidBootRemedy(pressure)
772
+ };
723
773
  }
724
774
  function liveOwnedDeviceCount({ sims = [], adbEmulators = [], config = null } = {}) {
725
775
  let count = 0;
@@ -955,30 +1005,19 @@ async function ensureAndroidBooted({ device, timeoutMs, out, logFile = null, ali
955
1005
  failed: true,
956
1006
  reason: `AVD ${device.avdName} is not Stim-owned by name; refusing to boot it.`
957
1007
  };
958
- if (resolved.serial) {
959
- const ready = await waitForBoot(resolved.serial, timeoutMs);
960
- if (!ready.ok) return {
961
- failed: true,
962
- reason: `Emulator ${resolved.serial} never reported boot completion. Diagnostic: ${JSON.stringify(ready.diagnostic)}`
963
- };
964
- return {
965
- ok: true,
966
- serial: resolved.serial
967
- };
968
- }
1008
+ if (resolved.serial) return waitForAndroidBoot({
1009
+ serial: resolved.serial,
1010
+ timeoutMs,
1011
+ out
1012
+ });
969
1013
  const freshSerial = `emulator-${device.consolePort}`;
970
- if (device.owned && device.serial === freshSerial) {
971
- const ready = await waitForBoot(freshSerial, timeoutMs);
972
- if (ready.ok) return {
973
- ok: true,
974
- serial: freshSerial
975
- };
976
- return {
977
- failed: true,
978
- reason: `Emulator ${freshSerial} never reported boot completion. Diagnostic: ${JSON.stringify(ready.diagnostic)}`
979
- };
980
- }
1014
+ if (device.owned && device.serial === freshSerial) return waitForAndroidBoot({
1015
+ serial: freshSerial,
1016
+ timeoutMs,
1017
+ out
1018
+ });
981
1019
  const serial = `emulator-${pickConsolePort(device.consolePort)}`;
1020
+ reportAndroidMemoryPressure(out);
982
1021
  out(chalk.dim(phaseLine("device", `booting ${device.avdName} as ${serial}`)));
983
1022
  let pid = null;
984
1023
  try {
@@ -989,15 +1028,13 @@ async function ensureAndroidBooted({ device, timeoutMs, out, logFile = null, ali
989
1028
  reason: `Could not start emulator for AVD ${device.avdName}: ${e?.message || e}`
990
1029
  };
991
1030
  }
992
- const ready = await waitForBoot(serial, timeoutMs, { aborted: emulatorGone(pid, alive) });
993
- if (!ready.ok) return {
994
- failed: true,
995
- reason: `${bootFailurePrefix(serial, ready.exited, timeoutMs)} Diagnostic: ${JSON.stringify(ready.diagnostic)}`
996
- };
997
- return {
998
- ok: true,
999
- serial
1000
- };
1031
+ return waitForAndroidBoot({
1032
+ serial,
1033
+ timeoutMs,
1034
+ pid,
1035
+ alive,
1036
+ out
1037
+ });
1001
1038
  }
1002
1039
  function pickConsolePort(recorded) {
1003
1040
  const live = liveAndroidConsolePorts();
@@ -1855,4 +1892,4 @@ async function buildIos({ root, udid = null, logWriter, project = null, scheme =
1855
1892
  };
1856
1893
  }
1857
1894
  //#endregion
1858
- export { unknownAndroidSystemImageRefusal as C, simslimIsOnPath as E, liveOwnedDeviceCount as S, unknownIosRuntimeRefusal as T, AvdRecoveryError as _, ccacheEnabled as a, ensureBooted as b, discoverXcodeProject as c, resolveScheme as d, startBuildHeartbeat as f, podInstallCommand as g, bundlerPin as h, buildIos as i, readBundleExecutable as l, describeDiagnostic as m, COMPILATION_CACHE_UNAVAILABLE as n, compilationCacheActivityLine as o, tailLines as p, HEARTBEAT_INTERVAL_MS as r, detectXcodeMajor as s, COMPILATION_CACHE_NOT_RUN as t, readBundleId as u, checkDeviceCapacity as v, unknownIosDeviceTypeRefusal as w, ensureOwnedDevice as x, clearIosAdoptionPending as y };
1895
+ export { liveOwnedDeviceCount as C, simslimIsOnPath as D, unknownIosRuntimeRefusal as E, ensureOwnedDevice as S, unknownIosDeviceTypeRefusal as T, AvdBootError as _, ccacheEnabled as a, clearIosAdoptionPending as b, discoverXcodeProject as c, resolveScheme as d, startBuildHeartbeat as f, podInstallCommand as g, bundlerPin as h, buildIos as i, readBundleExecutable as l, describeDiagnostic as m, COMPILATION_CACHE_UNAVAILABLE as n, compilationCacheActivityLine as o, tailLines as p, HEARTBEAT_INTERVAL_MS as r, detectXcodeMajor as s, COMPILATION_CACHE_NOT_RUN as t, readBundleId as u, AvdRecoveryError as v, unknownAndroidSystemImageRefusal as w, ensureBooted as x, checkDeviceCapacity as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stim",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Stim: fast, isolated React Native environments for coding agents",
5
5
  "keywords": [
6
6
  "agent",
@@ -42,16 +42,16 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@expo/fingerprint": "^0.20.10",
45
- "@stim-cli/cache": "^1.3.0",
46
- "@stim-cli/core": "^1.3.0",
47
- "@stim-cli/metro": "^1.3.0",
45
+ "@stim-cli/cache": "^1.3.1",
46
+ "@stim-cli/core": "^1.3.1",
47
+ "@stim-cli/metro": "^1.3.1",
48
48
  "chalk": "^5.4.1",
49
49
  "commander": "^13.1.0",
50
50
  "unique-pid": "0.1.1",
51
51
  "ws": "^8.21.3"
52
52
  },
53
53
  "devDependencies": {
54
- "@stim-cli/expo-build-cache": "1.3.0",
54
+ "@stim-cli/expo-build-cache": "1.3.1",
55
55
  "@types/ws": "^8.18.1"
56
56
  },
57
57
  "engines": {