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.
- package/README.md +23 -155
- package/dist/{android-BRgBYzU0.mjs → android-BPGizezh.mjs} +112 -135
- package/dist/{android-DeYdjjBP.mjs → android-DEgo4oCo.mjs} +2 -2
- package/dist/{android-DWssqHQ8.mjs → android-_y4Ohi5z.mjs} +54 -15
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{android-cas-SWIjzeuL.mjs → android-cas-eiExNLf7.mjs} +21 -14
- package/dist/app-install-Uf3a83Tv.mjs +819 -0
- package/dist/{build-lock-CgtsB6TV.mjs → build-lock-DPXPLgTc.mjs} +120 -24
- package/dist/build-progress-CVqkfPC6.mjs +188 -0
- package/dist/{cache-manifest-CYJi8-Hx.mjs → cache-manifest-Dg7OnMrp.mjs} +4 -4
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +22 -19
- package/dist/collector-run.d.mts +2 -0
- package/dist/collector-run.mjs +10 -9
- package/dist/{command-output-B3ycpsYv.mjs → command-output-gByVmIjy.mjs} +11 -2
- package/dist/{config-B7iyKWkL.mjs → config-Cp9lM3wX.mjs} +187 -57
- package/dist/{dependency-state-D0M7oKA7.mjs → dependency-state-Bq5DcLGn.mjs} +2 -2
- package/dist/{deps-oCXVNEqQ.mjs → deps-Cip5vUm1.mjs} +8 -5
- package/dist/{detached-entry-Bpo6ZY_I.mjs → detached-entry-KEu0_AXL.mjs} +1 -1
- package/dist/{device-BUoZyMoR.mjs → dev-client-HyqISM0h.mjs} +1178 -635
- package/dist/{device-RdujjHLB.mjs → device-D4U-xLty.mjs} +13 -20
- package/dist/{device-lease-Ffz_M5t0.mjs → device-lease-Crs-HkJY.mjs} +16 -9
- package/dist/{device-pool-BxRwdufO.mjs → device-pool-CnTAz8X1.mjs} +7 -7
- package/dist/{device-remote-ByN8P6CB.mjs → device-remote-AQ5rQPqr.mjs} +482 -35
- package/dist/{doctor-BMt156qe.mjs → doctor-B_Ei3bZu.mjs} +95 -107
- package/dist/{error-diagnostics-D1Kaf-eT.mjs → error-diagnostics-Vfz83GCF.mjs} +22 -16
- package/dist/exec-jIAlgilk.mjs +132 -0
- package/dist/{gc-v2YcoJvm.mjs → gc-Ckw8RQHi.mjs} +763 -126
- package/dist/{guide-BTAlD1_y.mjs → guide-BiAbhs1J.mjs} +891 -501
- package/dist/{guide-status-Craq9z0t.mjs → guide-status-BAMVU0ZA.mjs} +5 -3
- package/dist/{ios-BcCiI4TS.mjs → ios-BL2NFckr.mjs} +43 -20
- package/dist/{ios-BP04pY5f.mjs → ios-BzUJWk1K.mjs} +141 -175
- package/dist/{ios-device-CauFJiYx.mjs → ios-device-D972i9wf.mjs} +149 -52
- package/dist/{ios-device-CFXA46ez.mjs → ios-device-DPsSm0v_.mjs} +3 -2
- package/dist/launch-verify-Q_OtW1Rf.mjs +365 -0
- package/dist/{logs-CakdBTtm.mjs → logs-CI9NQSK7.mjs} +18 -13
- package/dist/{logs-query-BGL-Pl12.mjs → logs-query-Cqma3WIu.mjs} +36 -28
- package/dist/{metro-C7bcJ0uo.mjs → metro-DrLHaMn2.mjs} +78 -8
- package/dist/{named-ports-DzMOlmaX.mjs → named-ports-CmLQSIRj.mjs} +4 -4
- package/dist/{ndjson-BZwI1NBv.mjs → ndjson-9uFNRwfe.mjs} +36 -3
- package/dist/{ownership-Cp52QAK1.mjs → ownership-D15Op8vN.mjs} +3 -3
- package/dist/{ownership-wolE-0Do.mjs → ownership-DCQPuWEc.mjs} +26 -7
- package/dist/{ports-BIbJaKNW.mjs → ports-BNKoWVWZ.mjs} +3 -3
- package/dist/{process-output-Dl5uKE03.mjs → process-output-Fpl8PYi8.mjs} +1 -1
- package/dist/{project-DDZWf_16.mjs → project-DS112DYB.mjs} +8 -3
- package/dist/{reload-BdypPbjM.mjs → reload-ZNJUo1pl.mjs} +12 -13
- package/dist/{server-bare-BQkyxa_b.mjs → server-bare-DWkkcIxV.mjs} +2 -2
- package/dist/{server-expo-BVAA1OqJ.mjs → server-expo-B_lctBR3.mjs} +8 -7
- package/dist/server-expo-CeILEu86.mjs +2 -0
- package/dist/settings-BKNh5rl4.mjs +376 -0
- package/dist/{settings-BXXorVM2.mjs → settings-D030k0t4.mjs} +464 -152
- package/dist/settings.schema.json +989 -0
- package/dist/{teardown-BJqEzPo_.mjs → sim-pool-KaIsp2Ft.mjs} +14 -419
- package/dist/simslim-B_LsGLuJ.mjs +259 -0
- package/dist/{slot-launch-ZUUe0TQP.mjs → slot-launch-DU9A-gYw.mjs} +4 -4
- package/dist/spawn-claims-Dn3C_N6w.mjs +49 -0
- package/dist/{start-CmxtOKjU.mjs → start-DYkkKF0s.mjs} +27 -31
- package/dist/{state-DZobzxLW.mjs → state-NcJzMEBF.mjs} +5 -3
- package/dist/{stats-CLg5RuDS.mjs → stats-B63-JVAY.mjs} +4 -4
- package/dist/{stats-BYcZ6n1h.mjs → stats-DG9e66Rz.mjs} +66 -5
- package/dist/status-S6ehL4Ui.mjs +932 -0
- package/dist/{stop-C8JW6kKp.mjs → stop-BO28HGqF.mjs} +101 -25
- package/dist/{stop-B1kOpYei.mjs → stop-T1R-cZRz.mjs} +2 -2
- package/dist/supervisor-run.mjs +52 -34
- package/dist/{workspace-process-lock-BYfZz_S-.mjs → workspace-process-lock-DWaiRD0e.mjs} +14 -9
- package/dist/{workspace-state-BT5E3SA2.mjs → workspace-state-DF2gCFhx.mjs} +52 -29
- package/dist/worktree-DKhSF0UX.mjs +2 -0
- package/dist/{worktree-CFLA-6MX.mjs → worktree-LGB-UwgG.mjs} +603 -59
- package/dist/{worktree-FG_ZKKdb.mjs → worktree-R_cUlE7s.mjs} +62 -41
- package/dist/{xcode-B6YaWeg0.mjs → xcode-BZqyxh3e.mjs} +216 -58
- package/package.json +5 -6
- package/skill/SKILL.md +2 -0
- package/dist/app-install-BDbsSgCl.mjs +0 -1175
- package/dist/build-slots-C-oAHRT1.mjs +0 -151
- package/dist/dev-client-BmT-ioFI.mjs +0 -797
- package/dist/exec-B29XNuhP.mjs +0 -77
- package/dist/reclaim-KJ-0uWEF.mjs +0 -361
- package/dist/server-expo-YDDG3eP7.mjs +0 -2
- package/dist/status-DdkLki47.mjs +0 -426
- package/dist/{metro-store-CDDZHtPl.mjs → metro-store-DzeWkfqW.mjs} +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { r as clockTime } from "./command-output-
|
|
5
|
-
import { f as takeLease, l as releaseWorkspaceLeases, n as fileLeaseIo, o as parseLeaseDuration } from "./device-lease-
|
|
6
|
-
import { d as waitForDevice, s as parseDeviceWait, t as selectFromPool } from "./device-pool-
|
|
7
|
-
import { c as listIosDevices, o as
|
|
1
|
+
import { G as parseDeviceSlotOption } from "./config-Cp9lM3wX.mjs";
|
|
2
|
+
import { o as findProjectRoot, t as NO_PROJECT_REFUSAL } from "./project-DS112DYB.mjs";
|
|
3
|
+
import { C as listAdbDevices, D as memoizeEmulatorProbe, I as probeEmulatorSerial, P as physicalDeviceModel, a as androidPoolNoCandidatesRefusal, i as androidPoolCandidates, z as resolvePhysicalDevice } from "./android-_y4Ohi5z.mjs";
|
|
4
|
+
import { r as clockTime } from "./command-output-gByVmIjy.mjs";
|
|
5
|
+
import { f as takeLease, l as releaseWorkspaceLeases, n as fileLeaseIo, o as parseLeaseDuration } from "./device-lease-Crs-HkJY.mjs";
|
|
6
|
+
import { d as waitForDevice, s as parseDeviceWait, t as selectFromPool } from "./device-pool-CnTAz8X1.mjs";
|
|
7
|
+
import { a as iosPoolCandidates, c as listIosDevices, o as iosPoolNoCandidatesRefusal, s as isWirelessIosDevice, u as resolveIosPhysicalDevice } from "./ios-device-D972i9wf.mjs";
|
|
8
8
|
import chalk from "chalk";
|
|
9
9
|
//#region src/commands/device.ts
|
|
10
10
|
const DEFAULT_FOR = "5m";
|
|
@@ -69,7 +69,8 @@ async function poolDevice(platform, idLabel, waitSeconds, deadline, root, d, slo
|
|
|
69
69
|
idLabel,
|
|
70
70
|
list: () => platform === "ios" ? iosPoolCandidates(d.listIosDevices()).map((entry) => ({
|
|
71
71
|
id: entry.udid,
|
|
72
|
-
name: entry.name
|
|
72
|
+
name: entry.name,
|
|
73
|
+
fallback: isWirelessIosDevice(entry)
|
|
73
74
|
})) : androidPoolCandidates(d.listAdbDevices(), isEmulator).map((entry) => ({ id: entry.serial })),
|
|
74
75
|
noCandidates: () => {
|
|
75
76
|
const resolved = platform === "ios" ? iosPoolNoCandidatesRefusal(d.listIosDevices()) : androidPoolNoCandidatesRefusal(d.listAdbDevices(), isEmulator);
|
|
@@ -121,11 +122,7 @@ async function runLock(platformArg, idArg, opts = {}, overrides = {}) {
|
|
|
121
122
|
remedy: "Run `stim device lock ios` or `stim device lock android`."
|
|
122
123
|
});
|
|
123
124
|
const root = d.findProjectRoot(process.cwd());
|
|
124
|
-
if (!root) return report(
|
|
125
|
-
code: "STIM_NO_PROJECT",
|
|
126
|
-
message: "Not in a React Native project (no package.json found).",
|
|
127
|
-
remedy: "Run this from the app directory -- the one holding package.json."
|
|
128
|
-
});
|
|
125
|
+
if (!root) return report(NO_PROJECT_REFUSAL);
|
|
129
126
|
const durationText = String(opts.for ?? DEFAULT_FOR).trim();
|
|
130
127
|
const duration = parseLeaseDuration(durationText);
|
|
131
128
|
if ("error" in duration) return report({
|
|
@@ -224,11 +221,7 @@ async function runUnlock(platformArg, opts = {}, overrides = {}) {
|
|
|
224
221
|
remedy: "Run `stim device unlock` for every lease this workspace holds, or name one platform."
|
|
225
222
|
});
|
|
226
223
|
const root = d.findProjectRoot(process.cwd());
|
|
227
|
-
if (!root) return report(
|
|
228
|
-
code: "STIM_NO_PROJECT",
|
|
229
|
-
message: "Not in a React Native project (no package.json found).",
|
|
230
|
-
remedy: "Run this from the app directory -- the one holding package.json."
|
|
231
|
-
});
|
|
224
|
+
if (!root) return report(NO_PROJECT_REFUSAL);
|
|
232
225
|
const released = d.releaseLeases(root, {
|
|
233
226
|
platform,
|
|
234
227
|
...opts.slot ? { slot: opts.slot } : {}
|
|
@@ -243,10 +236,10 @@ async function runUnlock(platformArg, opts = {}, overrides = {}) {
|
|
|
243
236
|
}
|
|
244
237
|
function registerDevice(program, deps = {}) {
|
|
245
238
|
const device = program.command("device").description("Lease a connected physical device to this workspace, and give it back");
|
|
246
|
-
device.command("lock").argument("<platform>", "ios or android").argument("[id]", "the UDID or serial to lease; without one, the first free connected device is used").description("Lease a connected physical device to this workspace for a declared time, so another workspace's `--device` run waits instead of installing over it. Nothing but this command and a `--device` run moves the expiry.").option("--for <duration>", `How long to hold it: a whole number of seconds or minutes from 10s to 30m (default ${DEFAULT_FOR})`).option("--wait <seconds>", "How long to wait for a device another workspace holds, before refusing with STIM_DEVICE_BUSY (default 60, 0 refuses at once)").option("--slot <name>", "Use this workspace device slot",
|
|
239
|
+
device.command("lock").argument("<platform>", "ios or android").argument("[id]", "the UDID or serial to lease; without one, the first free connected device is used").description("Lease a connected physical device to this workspace for a declared time, so another workspace's `--device` run waits instead of installing over it. Nothing but this command and a `--device` run moves the expiry.").option("--for <duration>", `How long to hold it: a whole number of seconds or minutes from 10s to 30m (default ${DEFAULT_FOR})`).option("--wait <seconds>", "How long to wait for a device another workspace holds, before refusing with STIM_DEVICE_BUSY (default 60, 0 refuses at once)").option("--slot <name>", "Use this workspace device slot", parseDeviceSlotOption).option("--json", "print the lease as JSON on stdout").action(async (platform, id, opts) => {
|
|
247
240
|
if ("code" in await runLock(platform, id, opts, deps)) process.exit(1);
|
|
248
241
|
});
|
|
249
|
-
device.command("unlock").argument("[platform]", "ios or android; without one, every lease this workspace holds is released").description("Release the device lease or leases this workspace holds. Releasing nothing is not an error.").option("--slot <name>", "Use this workspace device slot",
|
|
242
|
+
device.command("unlock").argument("[platform]", "ios or android; without one, every lease this workspace holds is released").description("Release the device lease or leases this workspace holds. Releasing nothing is not an error.").option("--slot <name>", "Use this workspace device slot", parseDeviceSlotOption).option("--json", "print the released leases as JSON on stdout").action(async (platform, opts) => {
|
|
250
243
|
const result = await runUnlock(platform, opts, deps);
|
|
251
244
|
if (!Array.isArray(result)) process.exit(1);
|
|
252
245
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { A as withDirLock, H as deviceSlotKey, J as validateDeviceSlot, W as parseDeviceSlotKey, u as getConfigDir } from "./config-Cp9lM3wX.mjs";
|
|
2
|
+
import { c as writeWorkspaceState, n as clearWorkspaceStateKeys, o as withWorkspaceStateLock, r as readWorkspaceState } from "./workspace-state-DF2gCFhx.mjs";
|
|
3
|
+
import { i as segment } from "./build-lock-DPXPLgTc.mjs";
|
|
4
4
|
import { mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
-
import { randomBytes } from "node:crypto";
|
|
6
5
|
import { join } from "node:path";
|
|
6
|
+
import { randomBytes } from "node:crypto";
|
|
7
7
|
const DEFAULT_LEASE_MS = 3e5;
|
|
8
8
|
const LEASE_SUFFIX = ".json";
|
|
9
9
|
const LOCK_SUFFIX = ".lock";
|
|
@@ -332,15 +332,21 @@ function selectPoolDevice({ candidates, leases, held = null, now }) {
|
|
|
332
332
|
id: held
|
|
333
333
|
};
|
|
334
334
|
}
|
|
335
|
-
|
|
335
|
+
const preferred = ordered.filter((candidate) => !candidate.fallback);
|
|
336
|
+
const pool = preferred.length > 0 ? preferred : ordered;
|
|
337
|
+
if (pool.length === 0) return { status: "none" };
|
|
336
338
|
const byId = new Map(leases.map((lease) => [lease.id, lease]));
|
|
337
|
-
const
|
|
338
|
-
for (const candidate of ordered) {
|
|
339
|
+
const free = (candidate) => {
|
|
339
340
|
const lease = byId.get(candidate.id);
|
|
340
|
-
|
|
341
|
+
return !lease || leaseIsExpired(lease, now);
|
|
342
|
+
};
|
|
343
|
+
const holders = [];
|
|
344
|
+
for (const candidate of pool) {
|
|
345
|
+
if (free(candidate)) return {
|
|
341
346
|
status: "selected",
|
|
342
347
|
candidate
|
|
343
348
|
};
|
|
349
|
+
const lease = byId.get(candidate.id);
|
|
344
350
|
holders.push({
|
|
345
351
|
id: lease.id,
|
|
346
352
|
holder: lease.holder,
|
|
@@ -349,7 +355,8 @@ function selectPoolDevice({ candidates, leases, held = null, now }) {
|
|
|
349
355
|
}
|
|
350
356
|
return {
|
|
351
357
|
status: "busy",
|
|
352
|
-
holders
|
|
358
|
+
holders,
|
|
359
|
+
spare: ordered.filter((candidate) => candidate.fallback && free(candidate)).map((candidate) => candidate.id)
|
|
353
360
|
};
|
|
354
361
|
}
|
|
355
362
|
function withHolderLock(io, root, fn) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as formatElapsed, r as clockTime } from "./command-output-
|
|
3
|
-
import {
|
|
4
|
-
import { a as parseLease, c as releaseRunLease, d as selectPoolDevice, f as takeLease, n as fileLeaseIo, r as leaseIsExpired, s as raiseLease, t as deviceLeasePath } from "./device-lease-
|
|
1
|
+
import { H as deviceSlotKey } from "./config-Cp9lM3wX.mjs";
|
|
2
|
+
import { a as formatElapsed, r as clockTime } from "./command-output-gByVmIjy.mjs";
|
|
3
|
+
import { a as VERIFY_TIMEOUT_MS, p as APP_READINESS_TIMEOUT_MS } from "./launch-verify-Q_OtW1Rf.mjs";
|
|
4
|
+
import { a as parseLease, c as releaseRunLease, d as selectPoolDevice, f as takeLease, n as fileLeaseIo, r as leaseIsExpired, s as raiseLease, t as deviceLeasePath } from "./device-lease-Crs-HkJY.mjs";
|
|
5
5
|
//#region src/engine/device-lease-run.ts
|
|
6
6
|
const LEASE_STEP_FLOOR_MS = 6e4;
|
|
7
7
|
const DEBUG_VERIFY_STEP_MS = VERIFY_TIMEOUT_MS + APP_READINESS_TIMEOUT_MS;
|
|
@@ -335,7 +335,7 @@ const NO_LEASE_FACTS = {
|
|
|
335
335
|
function unreadableSentence(unreadable) {
|
|
336
336
|
return unreadable.length ? ` Unreadable lease file, so no run may take that device around it: ${unreadable.join("; ")}.` : "";
|
|
337
337
|
}
|
|
338
|
-
function poolBusyRefusal(holders, leases, unreadable, now, waitSeconds) {
|
|
338
|
+
function poolBusyRefusal(holders, leases, unreadable, now, waitSeconds, spare = [], idLabel = "id") {
|
|
339
339
|
const named = holders.map((holder) => `${holder.id} (${holder.holder}, until ${leaseExpiryText(holder.expiresAt, now)})`);
|
|
340
340
|
const first = holders[0];
|
|
341
341
|
const lease = first ? leases.find((entry) => entry.id === first.id) : void 0;
|
|
@@ -348,7 +348,7 @@ function poolBusyRefusal(holders, leases, unreadable, now, waitSeconds) {
|
|
|
348
348
|
return {
|
|
349
349
|
code: DEVICE_BUSY,
|
|
350
350
|
message: `Every connected device is leased by another workspace${waitSeconds > 0 ? `, and this run waited ${waitSeconds}s for one` : ""}: ${named.join("; ")}.${unreadableSentence(unreadable)}`,
|
|
351
|
-
remedy: "Wait longer with `--wait <seconds>`, connect another device, or pass `--no-wait` to install anyway -- which takes no lease and, when both workspaces build the same app id, terminates the holder's running app.",
|
|
351
|
+
remedy: (spare.length ? `Also connected and free: ${spare.join(", ")}. Name one with \`--device <${idLabel}>\` to use it now. ` : "") + "Wait longer with `--wait <seconds>`, connect another device, or pass `--no-wait` to install anyway -- which takes no lease and, when both workspaces build the same app id, terminates the holder's running app.",
|
|
352
352
|
lease: {
|
|
353
353
|
platform: lease?.platform ?? null,
|
|
354
354
|
id: first.id,
|
|
@@ -401,7 +401,7 @@ async function selectFromPool({ root, platform, slot = "default", idLabel, list,
|
|
|
401
401
|
}
|
|
402
402
|
if (now() >= until) return {
|
|
403
403
|
status: "refused",
|
|
404
|
-
refusal: poolBusyRefusal(selection.holders, leases, unreadable, now(), waitSeconds)
|
|
404
|
+
refusal: poolBusyRefusal(selection.holders, leases, unreadable, now(), waitSeconds, selection.spare, idLabel)
|
|
405
405
|
};
|
|
406
406
|
if (lastLine === null || now() - lastLine >= 3e4) {
|
|
407
407
|
lastLine = now();
|