stim 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +23 -155
  2. package/dist/{android-BRgBYzU0.mjs → android-BPGizezh.mjs} +112 -135
  3. package/dist/{android-DeYdjjBP.mjs → android-DEgo4oCo.mjs} +2 -2
  4. package/dist/{android-DWssqHQ8.mjs → android-_y4Ohi5z.mjs} +54 -15
  5. package/dist/android-cas-compiler.mjs +2 -2
  6. package/dist/{android-cas-SWIjzeuL.mjs → android-cas-eiExNLf7.mjs} +21 -14
  7. package/dist/app-install-Uf3a83Tv.mjs +819 -0
  8. package/dist/{build-lock-CgtsB6TV.mjs → build-lock-DPXPLgTc.mjs} +120 -24
  9. package/dist/build-progress-CVqkfPC6.mjs +188 -0
  10. package/dist/{cache-manifest-CYJi8-Hx.mjs → cache-manifest-Dg7OnMrp.mjs} +4 -4
  11. package/dist/cache-manifest.mjs +1 -1
  12. package/dist/cli.mjs +22 -19
  13. package/dist/collector-run.d.mts +2 -0
  14. package/dist/collector-run.mjs +10 -9
  15. package/dist/{command-output-B3ycpsYv.mjs → command-output-gByVmIjy.mjs} +11 -2
  16. package/dist/{config-B7iyKWkL.mjs → config-Cp9lM3wX.mjs} +187 -57
  17. package/dist/{dependency-state-D0M7oKA7.mjs → dependency-state-Bq5DcLGn.mjs} +2 -2
  18. package/dist/{deps-oCXVNEqQ.mjs → deps-Cip5vUm1.mjs} +8 -5
  19. package/dist/{detached-entry-Bpo6ZY_I.mjs → detached-entry-KEu0_AXL.mjs} +1 -1
  20. package/dist/{device-BUoZyMoR.mjs → dev-client-HyqISM0h.mjs} +1178 -635
  21. package/dist/{device-RdujjHLB.mjs → device-D4U-xLty.mjs} +13 -20
  22. package/dist/{device-lease-Ffz_M5t0.mjs → device-lease-Crs-HkJY.mjs} +16 -9
  23. package/dist/{device-pool-BxRwdufO.mjs → device-pool-CnTAz8X1.mjs} +7 -7
  24. package/dist/{device-remote-ByN8P6CB.mjs → device-remote-AQ5rQPqr.mjs} +482 -35
  25. package/dist/{doctor-BMt156qe.mjs → doctor-B_Ei3bZu.mjs} +95 -107
  26. package/dist/{error-diagnostics-D1Kaf-eT.mjs → error-diagnostics-Vfz83GCF.mjs} +22 -16
  27. package/dist/exec-jIAlgilk.mjs +132 -0
  28. package/dist/{gc-v2YcoJvm.mjs → gc-Ckw8RQHi.mjs} +763 -126
  29. package/dist/{guide-BTAlD1_y.mjs → guide-BiAbhs1J.mjs} +891 -501
  30. package/dist/{guide-status-Craq9z0t.mjs → guide-status-BAMVU0ZA.mjs} +5 -3
  31. package/dist/{ios-BcCiI4TS.mjs → ios-BL2NFckr.mjs} +43 -20
  32. package/dist/{ios-BP04pY5f.mjs → ios-BzUJWk1K.mjs} +141 -175
  33. package/dist/{ios-device-CauFJiYx.mjs → ios-device-D972i9wf.mjs} +149 -52
  34. package/dist/{ios-device-CFXA46ez.mjs → ios-device-DPsSm0v_.mjs} +3 -2
  35. package/dist/launch-verify-Q_OtW1Rf.mjs +365 -0
  36. package/dist/{logs-CakdBTtm.mjs → logs-CI9NQSK7.mjs} +18 -13
  37. package/dist/{logs-query-BGL-Pl12.mjs → logs-query-Cqma3WIu.mjs} +36 -28
  38. package/dist/{metro-C7bcJ0uo.mjs → metro-DrLHaMn2.mjs} +78 -8
  39. package/dist/{named-ports-DzMOlmaX.mjs → named-ports-CmLQSIRj.mjs} +4 -4
  40. package/dist/{ndjson-BZwI1NBv.mjs → ndjson-9uFNRwfe.mjs} +36 -3
  41. package/dist/{ownership-Cp52QAK1.mjs → ownership-D15Op8vN.mjs} +3 -3
  42. package/dist/{ownership-wolE-0Do.mjs → ownership-DCQPuWEc.mjs} +26 -7
  43. package/dist/{ports-BIbJaKNW.mjs → ports-BNKoWVWZ.mjs} +3 -3
  44. package/dist/{process-output-Dl5uKE03.mjs → process-output-Fpl8PYi8.mjs} +1 -1
  45. package/dist/{project-DDZWf_16.mjs → project-DS112DYB.mjs} +8 -3
  46. package/dist/{reload-BdypPbjM.mjs → reload-ZNJUo1pl.mjs} +12 -13
  47. package/dist/{server-bare-BQkyxa_b.mjs → server-bare-DWkkcIxV.mjs} +2 -2
  48. package/dist/{server-expo-BVAA1OqJ.mjs → server-expo-B_lctBR3.mjs} +8 -7
  49. package/dist/server-expo-CeILEu86.mjs +2 -0
  50. package/dist/settings-BKNh5rl4.mjs +376 -0
  51. package/dist/{settings-BXXorVM2.mjs → settings-D030k0t4.mjs} +464 -152
  52. package/dist/settings.schema.json +989 -0
  53. package/dist/{teardown-BJqEzPo_.mjs → sim-pool-KaIsp2Ft.mjs} +14 -419
  54. package/dist/simslim-B_LsGLuJ.mjs +259 -0
  55. package/dist/{slot-launch-ZUUe0TQP.mjs → slot-launch-DU9A-gYw.mjs} +4 -4
  56. package/dist/spawn-claims-Dn3C_N6w.mjs +49 -0
  57. package/dist/{start-CmxtOKjU.mjs → start-DYkkKF0s.mjs} +27 -31
  58. package/dist/{state-DZobzxLW.mjs → state-NcJzMEBF.mjs} +5 -3
  59. package/dist/{stats-CLg5RuDS.mjs → stats-B63-JVAY.mjs} +4 -4
  60. package/dist/{stats-BYcZ6n1h.mjs → stats-DG9e66Rz.mjs} +66 -5
  61. package/dist/status-S6ehL4Ui.mjs +932 -0
  62. package/dist/{stop-C8JW6kKp.mjs → stop-BO28HGqF.mjs} +101 -25
  63. package/dist/{stop-B1kOpYei.mjs → stop-T1R-cZRz.mjs} +2 -2
  64. package/dist/supervisor-run.mjs +52 -34
  65. package/dist/{workspace-process-lock-BYfZz_S-.mjs → workspace-process-lock-DWaiRD0e.mjs} +14 -9
  66. package/dist/{workspace-state-BT5E3SA2.mjs → workspace-state-DF2gCFhx.mjs} +52 -29
  67. package/dist/worktree-DKhSF0UX.mjs +2 -0
  68. package/dist/{worktree-CFLA-6MX.mjs → worktree-LGB-UwgG.mjs} +603 -59
  69. package/dist/{worktree-FG_ZKKdb.mjs → worktree-R_cUlE7s.mjs} +62 -41
  70. package/dist/{xcode-B6YaWeg0.mjs → xcode-BZqyxh3e.mjs} +216 -58
  71. package/package.json +5 -6
  72. package/skill/SKILL.md +2 -0
  73. package/dist/app-install-BDbsSgCl.mjs +0 -1175
  74. package/dist/build-slots-C-oAHRT1.mjs +0 -151
  75. package/dist/dev-client-BmT-ioFI.mjs +0 -797
  76. package/dist/exec-B29XNuhP.mjs +0 -77
  77. package/dist/reclaim-KJ-0uWEF.mjs +0 -361
  78. package/dist/server-expo-YDDG3eP7.mjs +0 -2
  79. package/dist/status-DdkLki47.mjs +0 -426
  80. package/dist/{metro-store-CDDZHtPl.mjs → metro-store-DzeWkfqW.mjs} +1 -1
@@ -1,9 +1,9 @@
1
- import { t as getExecutor } from "./exec-B29XNuhP.mjs";
2
- import { i as pidExists, o as signalProcessTree } from "./metro-C7bcJ0uo.mjs";
3
- import { c as androidDataPartitionSizeBytes } from "./settings-BXXorVM2.mjs";
1
+ import { t as getExecutor } from "./exec-jIAlgilk.mjs";
2
+ import { a as pidExists, l as signalProcessTree } from "./metro-DrLHaMn2.mjs";
3
+ import { s as androidDataPartitionSizeBytes } from "./settings-D030k0t4.mjs";
4
4
  import { existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
5
- import { homedir, tmpdir } from "os";
6
5
  import { dirname, isAbsolute, join, resolve } from "path";
6
+ import { homedir, tmpdir } from "os";
7
7
  //#region src/devices/android.ts
8
8
  const ANDROID_ABIS = /* @__PURE__ */ new Set([
9
9
  "armeabi-v7a",
@@ -199,9 +199,13 @@ function ownedAvdName(label) {
199
199
  const clean = sanitizeAvdLabel(label);
200
200
  return `stim-${clean.startsWith("stim-") ? clean.slice(5) : clean}`;
201
201
  }
202
+ const AVDMANAGER_DELETE_TIMEOUT_MS = 12e4;
202
203
  function deleteAvd(avdName) {
203
204
  if (!avdName?.startsWith("stim-")) throw new Error(`Refusing to delete AVD "${avdName}": not a Stim-owned AVD (name must start with "stim-").`);
204
- getExecutor().run(`${androidTool("avdmanager")} delete avd -n "${avdName}"`);
205
+ getExecutor().run(`${androidTool("avdmanager")} delete avd -n "${avdName}"`, {
206
+ timeoutMs: AVDMANAGER_DELETE_TIMEOUT_MS,
207
+ killSignal: "SIGKILL"
208
+ });
205
209
  }
206
210
  function parseAvdList(text) {
207
211
  return text.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("INFO") && !l.startsWith("WARNING"));
@@ -662,6 +666,9 @@ function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process
662
666
  avdName,
663
667
  "-port",
664
668
  String(consolePort),
669
+ "-grpc",
670
+ String(consolePort + 3e3),
671
+ "-grpc-use-token",
665
672
  ...headlessEmulatorArgs(),
666
673
  ...suppressEmulatorCrashConsent({ platform })
667
674
  ], {
@@ -852,20 +859,52 @@ function waitForAndroidEmulatorShutdown(avdName, shutdown, { timeoutMs = ANDROID
852
859
  }
853
860
  if (!directoryExists(directory)) throw new Error(`Could not verify the content directory for owned AVD ${avdName} after shutdown.`);
854
861
  }
855
- function getAvdNameForSerial(serial, { timeoutMs } = {}) {
856
- const out = getExecutor().runQuiet(`${androidTool("adb")} -s ${serial} emu avd name`, { timeoutMs });
862
+ const EMU_AVD_NAME_TIMEOUT_MS = 1e4;
863
+ function getAvdNameForSerial(serial, { timeoutMs = EMU_AVD_NAME_TIMEOUT_MS } = {}) {
864
+ const out = getExecutor().runQuiet(`${androidTool("adb")} -s ${serial} emu avd name`, {
865
+ timeoutMs: Math.min(timeoutMs, EMU_AVD_NAME_TIMEOUT_MS),
866
+ killSignal: "SIGKILL"
867
+ });
857
868
  if (!out) return null;
858
869
  return out.split("\n")[0]?.trim() || null;
859
870
  }
860
- function resolveOwnedAvdSerial(avdName, { timeoutMs } = {}) {
871
+ function resolveOwnedAvdSerial(avdName, opts = {}) {
872
+ return ownedAvdSerialResolver(opts)(avdName);
873
+ }
874
+ function once(read) {
875
+ let result;
876
+ return () => {
877
+ if (!result) try {
878
+ result = { value: read() };
879
+ } catch (error) {
880
+ result = { error };
881
+ }
882
+ if ("error" in result) throw result.error;
883
+ return result.value;
884
+ };
885
+ }
886
+ /**
887
+ * `resolveOwnedAvdSerial` for several AVDs against one reading of the AVD list, `adb devices`, and
888
+ * each emulator's AVD name. The timeout budget starts when the resolver is created.
889
+ */
890
+ function ownedAvdSerialResolver({ timeoutMs } = {}) {
861
891
  const started = Date.now();
862
892
  const remaining = () => ({ timeoutMs: timeoutMs === void 0 ? void 0 : Math.max(1, timeoutMs - (Date.now() - started)) });
863
- if (!listAvds(remaining()).includes(avdName)) return { missing: true };
864
- if (!avdName?.startsWith("stim-")) return { notOwned: true };
865
- const adb = listAdbDevices(remaining());
866
- const match = [...adb.emulators, ...adb.unhealthy.filter((entry) => entry.kind === "emulator" && entry.consolePort !== void 0)].find((e) => getAvdNameForSerial(e.serial, remaining()) === avdName);
867
- if (match) return { serial: match.serial };
868
- return { notRunning: true };
893
+ const avds = once(() => listAvds(remaining()));
894
+ const adb = once(() => listAdbDevices(remaining()));
895
+ const names = /* @__PURE__ */ new Map();
896
+ const avdNameOf = (serial) => {
897
+ if (!names.has(serial)) names.set(serial, getAvdNameForSerial(serial, remaining()));
898
+ return names.get(serial);
899
+ };
900
+ return (avdName) => {
901
+ if (!avds().includes(avdName)) return { missing: true };
902
+ if (!avdName?.startsWith("stim-")) return { notOwned: true };
903
+ const devices = adb();
904
+ const match = [...devices.emulators, ...devices.unhealthy.filter((entry) => entry.kind === "emulator" && entry.consolePort !== void 0)].find((e) => avdNameOf(e.serial) === avdName);
905
+ if (match) return { serial: match.serial };
906
+ return { notRunning: true };
907
+ };
869
908
  }
870
909
  //#endregion
871
- export { ownedAvdName as A, waitForBoot as B, listAvds as C, nextConsolePort as D, memoizeEmulatorProbe as E, resetAdoptedAvd as F, resolveOwnedAvdSerial as I, resolvePhysicalDevice as L, physicalDeviceModel as M, pickDefaultSystemImage as N, ownedAvdDirectory as O, probeEmulatorSerial as P, shutdownAndroidEmulator as R, listAdbDevices as S, listOrphanedAvdDirectories as T, emulatorFailureRemedy as _, androidPoolNoCandidatesRefusal as a, getAvdNameForSerial as b, assertOwnedAvdStopped as c, avdStorageRoots as d, bootAndroidEmulator as f, emulatorDiskSpaceRemedy as g, deleteAvd as h, androidPoolCandidates as i, ownedAvdSystemImage as j, ownedAvdMatchesConfiguration as k, avdPathExists as l, createOwnedAvd as m, androidDeviceAbi as n, androidSystemImageAbi as o, configureNewOwnedAvd as p, androidHome as r, androidToolCwd as s, androidBuildToolName as t, avdPoolConfiguration as u, extractEmulatorFailure as v, listInstalledSystemImages as w, hostSystemImageArch as x, findBuildTool as y, waitForAndroidEmulatorShutdown as z };
910
+ export { ownedAvdMatchesConfiguration as A, shutdownAndroidEmulator as B, listAdbDevices as C, memoizeEmulatorProbe as D, listOrphanedAvdDirectories as E, pickDefaultSystemImage as F, waitForBoot as H, probeEmulatorSerial as I, resetAdoptedAvd as L, ownedAvdSerialResolver as M, ownedAvdSystemImage as N, nextConsolePort as O, physicalDeviceModel as P, resolveOwnedAvdSerial as R, hostSystemImageArch as S, listInstalledSystemImages as T, waitForAndroidEmulatorShutdown as V, emulatorDiskSpaceRemedy as _, androidPoolNoCandidatesRefusal as a, findBuildTool as b, androidToolPath as c, avdPoolConfiguration as d, avdStorageRoots as f, deleteAvd as g, createOwnedAvd as h, androidPoolCandidates as i, ownedAvdName as j, ownedAvdDirectory as k, assertOwnedAvdStopped as l, configureNewOwnedAvd as m, androidDeviceAbi as n, androidSystemImageAbi as o, bootAndroidEmulator as p, androidHome as r, androidToolCwd as s, androidBuildToolName as t, avdPathExists as u, emulatorFailureRemedy as v, listAvds as w, getAvdNameForSerial as x, extractEmulatorFailure as y, resolvePhysicalDevice as z };
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { t as getExecutor } from "./exec-B29XNuhP.mjs";
2
+ import { t as getExecutor } from "./exec-jIAlgilk.mjs";
3
3
  import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
4
- import { createHash, randomUUID } from "node:crypto";
5
4
  import { join } from "node:path";
5
+ import { createHash, randomUUID } from "node:crypto";
6
6
  import { once } from "node:events";
7
7
  //#region bin/android-cas-compiler.ts
8
8
  const context = process.env.STIM_ANDROID_CAS_CONTEXT;
@@ -1,14 +1,15 @@
1
- import { t as getExecutor } from "./exec-B29XNuhP.mjs";
2
- import { D as withDirLock, u as getConfigDir } from "./config-B7iyKWkL.mjs";
3
- import { r as register } from "./cache-manifest-CYJi8-Hx.mjs";
4
- import { _ as workspaceLogsDir, c as ensureWorkspaceStorage, u as sharedCcache } from "./workspace-state-BT5E3SA2.mjs";
5
- import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Dl5uKE03.mjs";
6
- import { r as androidHome } from "./android-DWssqHQ8.mjs";
7
- import { l as phaseLine } from "./command-output-B3ycpsYv.mjs";
8
- import { d as startBuildHeartbeat, n as HEARTBEAT_INTERVAL_MS } from "./xcode-B6YaWeg0.mjs";
1
+ import { A as withDirLock, M as readJsonFile, j as isJsonObject, u as getConfigDir } from "./config-Cp9lM3wX.mjs";
2
+ import { t as getExecutor } from "./exec-jIAlgilk.mjs";
3
+ import { r as register } from "./cache-manifest-Dg7OnMrp.mjs";
4
+ import { b as workspaceLogsDir, f as sharedCcache, u as ensureWorkspaceStorage } from "./workspace-state-DF2gCFhx.mjs";
5
+ import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
6
+ import { r as androidHome } from "./android-_y4Ohi5z.mjs";
7
+ import { l as phaseLine } from "./command-output-gByVmIjy.mjs";
8
+ import { n as spawnDeclared } from "./spawn-claims-Dn3C_N6w.mjs";
9
+ import { d as startBuildHeartbeat, n as HEARTBEAT_INTERVAL_MS } from "./xcode-BZqyxh3e.mjs";
9
10
  import { accessSync, constants, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs";
10
- import { createHash, randomUUID } from "node:crypto";
11
11
  import { dirname, isAbsolute, join, relative, sep } from "node:path";
12
+ import { createHash, randomUUID } from "node:crypto";
12
13
  import { fileURLToPath } from "node:url";
13
14
  import chalk from "chalk";
14
15
  /** The ABI name a build for every ABI has to fit; `stim android` narrows a build to the device's. */
@@ -833,7 +834,7 @@ async function buildAndroid({ root, logWriter, variant = null, abi = null }, { s
833
834
  if (ccache) resetStatsLog(ccache.statsLog);
834
835
  let child;
835
836
  try {
836
- child = spawn(project.gradlew, args, {
837
+ child = spawnDeclared(() => spawn(project.gradlew, args, {
837
838
  cwd: project.androidDir,
838
839
  stdio: [
839
840
  "ignore",
@@ -848,7 +849,7 @@ async function buildAndroid({ root, logWriter, variant = null, abi = null }, { s
848
849
  TERM: "dumb",
849
850
  FORCE_COLOR: "0"
850
851
  }
851
- });
852
+ }));
852
853
  } catch (err) {
853
854
  return spawnFailure(err, project, now() - startedAt);
854
855
  }
@@ -994,10 +995,16 @@ function directory(path) {
994
995
  return false;
995
996
  }
996
997
  }
998
+ function isAndroidCasToolchain(value) {
999
+ return CAS_TOOLCHAIN_FIELDS.every((field) => typeof value[field] === "string");
1000
+ }
997
1001
  function readAndroidCasToolchain(manifest) {
998
- const toolchain = JSON.parse(readFileSync(manifest, "utf8"));
999
- const missing = CAS_TOOLCHAIN_FIELDS.filter((field) => typeof toolchain?.[field] !== "string");
1000
- if (missing.length > 0) throw new Error(`${manifest} declares no ${missing.join(", ")}.`);
1002
+ const parsed = readJsonFile(manifest);
1003
+ const toolchain = isJsonObject(parsed) ? parsed : {};
1004
+ if (!isAndroidCasToolchain(toolchain)) {
1005
+ const missing = CAS_TOOLCHAIN_FIELDS.filter((field) => typeof toolchain[field] !== "string");
1006
+ throw new Error(`${manifest} declares no ${missing.join(", ")}.`);
1007
+ }
1001
1008
  const notExecutable = CAS_TOOLCHAIN_BINARIES.filter((field) => !executableFile(toolchain[field]));
1002
1009
  if (notExecutable.length > 0) throw new Error(`${manifest} names no executable ${notExecutable.join(", ")}.`);
1003
1010
  if (!directory(toolchain.resourceDir)) throw new Error(`${manifest} names resourceDir ${toolchain.resourceDir}, which is not a directory.`);