stim 1.2.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.
- package/README.md +34 -3
- package/dist/{android-Bcmev2s2.mjs → android-CT-PkXUh.mjs} +157 -62
- package/dist/{android-cas-D6HPZ6UQ.mjs → android-cas-DXorPCi_.mjs} +5 -5
- package/dist/android-hMj83VpN.mjs +1374 -0
- package/dist/{app-install-NFxUahnH.mjs → app-install-DIp9riNx.mjs} +6 -6
- package/dist/{build-slots-D0b6sJyo.mjs → build-slots-C4AouyNz.mjs} +2 -2
- package/dist/{cache-manifest-Cu4_Znw9.mjs → cache-manifest-CXR-Y8pH.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +13 -13
- package/dist/collector-run.d.mts +3 -1
- package/dist/collector-run.mjs +33 -8
- package/dist/{config-CMtIaTk9.mjs → config-CcefMY2Q.mjs} +93 -12
- package/dist/{deps-BLBsTNDS.mjs → deps-0Yt0Inly.mjs} +1 -1
- package/dist/{dev-client-RpvXxCXV.mjs → dev-client-VfSZNLT4.mjs} +186 -9
- package/dist/{device-CoCPmazS.mjs → device-Bbv45Z9Z.mjs} +19 -11
- package/dist/{device-lease-Dpik41RY.mjs → device-lease-CJwK7OZr.mjs} +107 -83
- package/dist/{device-pool-B5pEVa3t.mjs → device-pool-CcBNTvM7.mjs} +18 -12
- package/dist/{device-remote-E81KAdXf.mjs → device-remote-DAA0Zm6Z.mjs} +7 -7
- package/dist/{doctor-CqPeMsSm.mjs → doctor-B4EITgQB.mjs} +11 -12
- package/dist/{doctor-D_CX7ib5.mjs → doctor-BueDfLYG.mjs} +4 -4
- package/dist/{error-diagnostics-Dw8Gn3yw.mjs → error-diagnostics-DwhNBFDU.mjs} +62 -52
- package/dist/{gc-B7KkDinF.mjs → gc-BRu62v4o.mjs} +66 -57
- package/dist/{guide-BS2Xc24o.mjs → guide-D95E0u3i.mjs} +307 -74
- package/dist/{ios-B7KLgIp5.mjs → ios-DAju3TVy.mjs} +183 -54
- package/dist/{ios-D1h1Di39.mjs → ios-Deh5js5V.mjs} +78 -40
- package/dist/{ios-device-xNt0Lg6v.mjs → ios-device-CWOM_S44.mjs} +1 -1
- package/dist/{logs-DcX9AvRF.mjs → logs-CAdwW6c2.mjs} +34 -6
- package/dist/{logs-query-oqn47Ffx.mjs → logs-query-Cdp5aaCH.mjs} +23 -6
- package/dist/{metro-COslRK_F.mjs → metro-CORqXyTL.mjs} +2 -2
- package/dist/{ndjson-DcAtEx_K.mjs → ndjson-BZwI1NBv.mjs} +5 -2
- package/dist/{ownership-CGPart6T.mjs → ownership-8O073GIC.mjs} +3 -3
- package/dist/{ownership-CYOyqxUo.mjs → ownership-DXcol4oU.mjs} +3 -3
- package/dist/{ownership-claim-7zRxxTfZ.mjs → ownership-claim-BtPtJVmq.mjs} +38 -23
- package/dist/{project-BBTVABUz.mjs → project-fKmuIaMI.mjs} +2 -2
- package/dist/{reclaim-C5Jmuahx.mjs → reclaim-CUmwucWG.mjs} +80 -74
- package/dist/{reload-Z8nKifAk.mjs → reload-CWpXoOgN.mjs} +32 -24
- package/dist/{server-bare-DEk37Mz2.mjs → server-bare-DEzPZLvf.mjs} +2 -2
- package/dist/server-expo-44em5Pmg.mjs +2 -0
- package/dist/{server-expo-C3ktAwUG.mjs → server-expo-DizT4OMk.mjs} +4 -4
- package/dist/{settings-DwU1_U_q.mjs → settings-DEJf6_kJ.mjs} +2 -2
- package/dist/slot-launch-CZklomj6.mjs +19 -0
- package/dist/{start-BrY4EuIg.mjs → start-B5G4NjiA.mjs} +11 -11
- package/dist/{state-CZ-ER-8d.mjs → state-B3XA2wp2.mjs} +9 -9
- package/dist/{stats-BCWEVLrM.mjs → stats-BR-kwj0B.mjs} +1 -1
- package/dist/{stats-BsF15Bti.mjs → stats-CaaQr4yN.mjs} +3 -3
- package/dist/{status-DFI1Hfpg.mjs → status-CI9clRSb.mjs} +55 -24
- package/dist/{stop-B7DR4awK.mjs → stop-CQhffpmX.mjs} +2 -2
- package/dist/{stop-Btg770vV.mjs → stop-CjlgDk0a.mjs} +93 -42
- package/dist/supervisor-run.d.mts +1 -2
- package/dist/supervisor-run.mjs +5 -5
- package/dist/{remote-cache-DDmJ1Roq.mjs → teardown--gESs9ck.mjs} +985 -887
- package/dist/{workspace-process-lock-BKfdys1q.mjs → workspace-process-lock-IBj1Towr.mjs} +1 -1
- package/dist/{worktree-BPTbI-LN.mjs → worktree-DtQGO9-s.mjs} +121 -111
- package/dist/{worktree-C79xx_kM.mjs → worktree-Eq6TLH8N.mjs} +1 -1
- package/dist/{xcode-DeKCribl.mjs → xcode-xnxyvJkD.mjs} +159 -96
- package/package.json +5 -5
- package/dist/android-K63_0UfF.mjs +0 -727
- package/dist/build-lock-BsVoLDaq.mjs +0 -645
- package/dist/server-expo-Drd7ksHu.mjs +0 -2
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { P as volumeRootFor, g as loadConfig, u as getConfigDir } from "./config-
|
|
3
|
-
import { D as workspaceLogsDir } from "./state-
|
|
4
|
-
import { f as listWorktrees } from "./worktree-
|
|
5
|
-
import { a as findProjectRoot, c as projectShortcut } from "./project-
|
|
6
|
-
import { a as isMetroRunning, i as resolveProjectMetro } from "./metro-
|
|
7
|
-
import { S as readParked, v as POOL_SETTING_REMEDY, x as parkedMaxSetting } from "./remote-cache-DDmJ1Roq.mjs";
|
|
2
|
+
import { P as volumeRootFor, g as loadConfig, u as getConfigDir, z as projectDeviceSlots } from "./config-CcefMY2Q.mjs";
|
|
3
|
+
import { D as workspaceLogsDir } from "./state-B3XA2wp2.mjs";
|
|
4
|
+
import { f as listWorktrees } from "./worktree-Eq6TLH8N.mjs";
|
|
5
|
+
import { a as findProjectRoot, c as projectShortcut } from "./project-fKmuIaMI.mjs";
|
|
6
|
+
import { a as isMetroRunning, i as resolveProjectMetro } from "./metro-CORqXyTL.mjs";
|
|
8
7
|
import { a as formatElapsed, r as clockTime, u as plural } from "./command-output-8wHMEde0.mjs";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
8
|
+
import { N as resolveOwnedAvdSerial } from "./android-hMj83VpN.mjs";
|
|
9
|
+
import { a as POOL_SETTING_REMEDY, c as parkedMaxSetting, l as readParked } from "./teardown--gESs9ck.mjs";
|
|
10
|
+
import { u as listAllIosSims } from "./ios-Deh5js5V.mjs";
|
|
11
|
+
import { i as listLeaseFiles } from "./device-lease-CJwK7OZr.mjs";
|
|
12
|
+
import { c as queryLogs } from "./logs-query-Cdp5aaCH.mjs";
|
|
13
|
+
import { t as resolveSupervisorTarget } from "./ownership-DXcol4oU.mjs";
|
|
14
|
+
import { i as readSupervisorState } from "./stop-CjlgDk0a.mjs";
|
|
15
15
|
import { existsSync } from "fs";
|
|
16
16
|
import { totalmem } from "os";
|
|
17
17
|
import chalk from "chalk";
|
|
@@ -24,14 +24,14 @@ function poolLine({ platform, parked, max }) {
|
|
|
24
24
|
const what = plural(parked, `parked ${platform === "ios" ? "iOS simulator" : "Android emulator"}`);
|
|
25
25
|
return max > 0 ? `pool: ${what} (max ${max})` : `pool: ${what} (parking off; gc --delete removes them)`;
|
|
26
26
|
}
|
|
27
|
-
function environmentState(project, { simsByUdid = {}, metro = null, worktrees = [], simsAvailable = true, androidRuntime = null, supervisor = null, logs = null } = {}) {
|
|
27
|
+
function environmentState(project, { simsByUdid = {}, metro = null, worktrees = [], simsAvailable = true, androidRuntime = null, androidRuntimes = {}, supervisor = null, logs = null } = {}) {
|
|
28
28
|
const ios = project.platforms?.ios;
|
|
29
29
|
const android = project.platforms?.android;
|
|
30
30
|
const sim = ios ? simsByUdid[ios.deviceUdid] : null;
|
|
31
31
|
const simBooted = Boolean(sim && sim.state === "Booted");
|
|
32
32
|
const metroRunning = Boolean(metro?.metro);
|
|
33
33
|
const androidDetected = androidRuntime ? Boolean(androidRuntime.serial) : Boolean(android?.serial);
|
|
34
|
-
|
|
34
|
+
let live = simBooted || metroRunning || androidDetected;
|
|
35
35
|
let memoryMb = 0;
|
|
36
36
|
if (simBooted) memoryMb += IOS_SIM_MB;
|
|
37
37
|
if (androidDetected) memoryMb += ANDROID_EMULATOR_MB;
|
|
@@ -48,8 +48,30 @@ function environmentState(project, { simsByUdid = {}, metro = null, worktrees =
|
|
|
48
48
|
if (androidRuntime.error) warnings.push(`could not check owned AVD ${android.avdName}: ${androidRuntime.error}`);
|
|
49
49
|
}
|
|
50
50
|
if (supervisor && supervisor.alive === false) warnings.push(`stale supervisor record for ${project.__path}`);
|
|
51
|
+
const slots = [];
|
|
52
|
+
for (const { slot, platforms } of projectDeviceSlots(project).slice(1)) {
|
|
53
|
+
const deviceState = environmentState({
|
|
54
|
+
...project,
|
|
55
|
+
platforms,
|
|
56
|
+
deviceSlots: void 0
|
|
57
|
+
}, {
|
|
58
|
+
simsByUdid,
|
|
59
|
+
simsAvailable,
|
|
60
|
+
metro,
|
|
61
|
+
androidRuntime: androidRuntimes[slot]
|
|
62
|
+
});
|
|
63
|
+
slots.push({
|
|
64
|
+
slot,
|
|
65
|
+
ios: deviceState.ios,
|
|
66
|
+
android: deviceState.android
|
|
67
|
+
});
|
|
68
|
+
memoryMb += deviceState.memoryMb - (metroRunning ? METRO_MB : 0);
|
|
69
|
+
live ||= deviceState.live;
|
|
70
|
+
warnings.push(...deviceState.warnings.map((warning) => `${slot}: ${warning}`));
|
|
71
|
+
}
|
|
51
72
|
return {
|
|
52
73
|
path: project.__path,
|
|
74
|
+
...slots.length ? { slots } : {},
|
|
53
75
|
live,
|
|
54
76
|
memoryMb,
|
|
55
77
|
warnings,
|
|
@@ -143,6 +165,7 @@ function deviceLeaseStates(entries, { root, now }) {
|
|
|
143
165
|
return {
|
|
144
166
|
path: entry.path,
|
|
145
167
|
platform: entry.platform,
|
|
168
|
+
...lease?.slot ? { slot: lease.slot } : {},
|
|
146
169
|
id: entry.id,
|
|
147
170
|
deviceName: lease?.deviceName ?? null,
|
|
148
171
|
holder: lease?.holder ?? null,
|
|
@@ -158,7 +181,7 @@ function deviceLeaseLines(states, now) {
|
|
|
158
181
|
if (states.length === 0) return [];
|
|
159
182
|
const lines = [`Device leases (${states.length}):`];
|
|
160
183
|
for (const state of states) {
|
|
161
|
-
const device = `${state.platform} ${state.id ?? state.path}${state.deviceName ? ` (${state.deviceName})` : ""}`;
|
|
184
|
+
const device = `${state.platform}${state.slot ? ` [${state.slot}]` : ""} ${state.id ?? state.path}${state.deviceName ? ` (${state.deviceName})` : ""}`;
|
|
162
185
|
if (!state.parsed || state.expiresAt === null) {
|
|
163
186
|
lines.push(` ${device} -- unreadable lease file, so nothing may take the device: ${state.path}`);
|
|
164
187
|
continue;
|
|
@@ -204,6 +227,7 @@ function statusCommand(program) {
|
|
|
204
227
|
metro,
|
|
205
228
|
worktrees,
|
|
206
229
|
simsAvailable,
|
|
230
|
+
androidRuntimes: Object.fromEntries(projectDeviceSlots(proj).slice(1).map(({ slot, platforms }) => [slot, platforms.android?.owned && platforms.android.avdName ? readAndroidRuntime(platforms.android.avdName) : null])),
|
|
207
231
|
androidRuntime: proj.platforms?.android?.owned && proj.platforms.android.avdName ? readAndroidRuntime(proj.platforms.android.avdName) : null,
|
|
208
232
|
supervisor,
|
|
209
233
|
logs: logFacts(path)
|
|
@@ -274,15 +298,22 @@ function statusCommand(program) {
|
|
|
274
298
|
const errs = n > 0 ? chalk.yellow(` (${n} error${n === 1 ? "" : "s"} since the last marker)`) : "";
|
|
275
299
|
console.log(chalk.dim(` logs: ${state.logs.dir}`) + errs);
|
|
276
300
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
301
|
+
for (const deviceState of [{
|
|
302
|
+
slot: "default",
|
|
303
|
+
ios: state.ios,
|
|
304
|
+
android: state.android
|
|
305
|
+
}, ...state.slots ?? []]) {
|
|
306
|
+
const slotLabel = deviceState.slot === "default" ? "" : ` [${deviceState.slot}]`;
|
|
307
|
+
if (deviceState.ios) {
|
|
308
|
+
const booted = deviceState.ios.state === "Booted" ? chalk.green("booted") : chalk.dim(deviceState.ios.state.toLowerCase());
|
|
309
|
+
const owned = deviceState.ios.owned ? chalk.dim(" (owned)") : "";
|
|
310
|
+
console.log(` ios${slotLabel}: ${chalk.cyan(deviceState.ios.name ?? deviceState.ios.udid)} ${booted}${owned}`);
|
|
311
|
+
}
|
|
312
|
+
if (deviceState.android) {
|
|
313
|
+
const kind = deviceState.android.physical ? chalk.dim("(physical)") : chalk.dim("(emulator)");
|
|
314
|
+
const observed = deviceState.android.state ? ` ${deviceState.android.state}${deviceState.android.serial ? ` (${deviceState.android.serial})` : ""}` : "";
|
|
315
|
+
console.log(` android${slotLabel}: ${chalk.cyan(deviceState.android.name)} ${kind}${observed}${deviceState.android.owned ? chalk.dim(" (owned)") : ""}`);
|
|
316
|
+
}
|
|
286
317
|
}
|
|
287
318
|
for (const w of state.warnings) console.log(chalk.yellow(` ! ${w}`));
|
|
288
319
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as resolveSupervisorTarget } from "./ownership-
|
|
2
|
-
import { a as resolveCollectorTargets, i as readSupervisorState, n as clearSupervisorState, o as runStop, r as readCollectorState, s as stopCommand, t as clearCollectorState } from "./stop-
|
|
1
|
+
import { t as resolveSupervisorTarget } from "./ownership-DXcol4oU.mjs";
|
|
2
|
+
import { a as resolveCollectorTargets, i as readSupervisorState, n as clearSupervisorState, o as runStop, r as readCollectorState, s as stopCommand, t as clearCollectorState } from "./stop-CjlgDk0a.mjs";
|
|
3
3
|
export { clearCollectorState, clearSupervisorState, stopCommand as default, readCollectorState, readSupervisorState, resolveCollectorTargets, resolveSupervisorTarget, runStop };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { C as withConfigLock, D as sameProcessRecord, E as inspectProcessIdentity, O as waitForProcessExit, S as upsertProject, a as clearSupervisor, f as getProject } from "./config-
|
|
2
|
-
import { _ as writeWorkspaceState, a as clearRemoteSession, c as readMetroTunnel, i as clearManagedMetroTunnel, m as withWorkspaceStateLock, o as clearWorkspaceStateKeys, p as readWorkspaceState, s as clearWorkspaceSupervisor, u as readRemoteSession } from "./state-
|
|
3
|
-
import { a as findProjectRoot } from "./project-
|
|
4
|
-
import { i as resolveProjectMetro, n as killMetroTree, r as pidExists } from "./metro-
|
|
5
|
-
import { n as verifyCollectorOwnership } from "./ownership-
|
|
6
|
-
import { d as resolveEasCliBin, h as teardownOwnedIosSim, m as teardownOwnedAvd } from "./remote-cache-DDmJ1Roq.mjs";
|
|
1
|
+
import { C as withConfigLock, D as sameProcessRecord, E as inspectProcessIdentity, L as deviceSlotPlatforms, O as waitForProcessExit, R as parseDeviceSlotKey, S as upsertProject, V as validateDeviceSlot, a as clearSupervisor, f as getProject, z as projectDeviceSlots } from "./config-CcefMY2Q.mjs";
|
|
2
|
+
import { T as workspaceDir, _ as writeWorkspaceState, a as clearRemoteSession, c as readMetroTunnel, i as clearManagedMetroTunnel, m as withWorkspaceStateLock, o as clearWorkspaceStateKeys, p as readWorkspaceState, s as clearWorkspaceSupervisor, u as readRemoteSession } from "./state-B3XA2wp2.mjs";
|
|
3
|
+
import { a as findProjectRoot } from "./project-fKmuIaMI.mjs";
|
|
4
|
+
import { i as resolveProjectMetro, n as killMetroTree, r as pidExists } from "./metro-CORqXyTL.mjs";
|
|
5
|
+
import { n as verifyCollectorOwnership } from "./ownership-8O073GIC.mjs";
|
|
7
6
|
import { f as releasedLeaseFact, l as phaseLine, u as plural } from "./command-output-8wHMEde0.mjs";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
7
|
+
import { n as teardownOwnedIosSim, t as teardownOwnedAvd, x as resolveEasCliBin } from "./teardown--gESs9ck.mjs";
|
|
8
|
+
import { t as withWorkspaceProcessLock } from "./workspace-process-lock-IBj1Towr.mjs";
|
|
9
|
+
import { l as releaseWorkspaceLeases } from "./device-lease-CJwK7OZr.mjs";
|
|
10
|
+
import { i as endRecordedSession } from "./device-remote-DAA0Zm6Z.mjs";
|
|
11
|
+
import { r as stopTunnel, t as resolveSupervisorTarget } from "./ownership-DXcol4oU.mjs";
|
|
11
12
|
import chalk from "chalk";
|
|
12
13
|
//#region src/commands/stop.ts
|
|
13
14
|
const DEFAULT_WAIT_MS = 1e4;
|
|
@@ -101,7 +102,47 @@ function defaultTeardownRemoteSession(root, sessionId) {
|
|
|
101
102
|
easBin: resolveEasCliBin(root)?.file ?? null
|
|
102
103
|
});
|
|
103
104
|
}
|
|
104
|
-
async function runStop(
|
|
105
|
+
async function runStop(options) {
|
|
106
|
+
if (options.slot === void 0) return stopWorkspace(options);
|
|
107
|
+
const slot = validateDeviceSlot(options.slot);
|
|
108
|
+
const root = options.root;
|
|
109
|
+
const project = options.project === void 0 ? getProject(root) : options.project;
|
|
110
|
+
const records = options.collectors === void 0 ? readCollectorState(root) : options.collectors;
|
|
111
|
+
const collectors = Object.fromEntries(Object.entries(records ?? {}).filter(([key]) => parseDeviceSlotKey(key)?.slot === slot));
|
|
112
|
+
const result = await stopWorkspace({
|
|
113
|
+
...options,
|
|
114
|
+
project: project ? {
|
|
115
|
+
...project,
|
|
116
|
+
platforms: deviceSlotPlatforms(project, slot),
|
|
117
|
+
deviceSlots: void 0,
|
|
118
|
+
supervisor: void 0,
|
|
119
|
+
metroPort: null
|
|
120
|
+
} : null,
|
|
121
|
+
state: null,
|
|
122
|
+
collectors,
|
|
123
|
+
remoteDevice: null,
|
|
124
|
+
metroTunnel: null,
|
|
125
|
+
clearCollectors: (projectRoot, expected) => withWorkspaceStateLock(projectRoot, () => {
|
|
126
|
+
clearCollectorState(projectRoot, expected);
|
|
127
|
+
return !Object.keys(readCollectorState(projectRoot)).some((key) => parseDeviceSlotKey(key)?.slot === slot);
|
|
128
|
+
}),
|
|
129
|
+
clearState: () => true,
|
|
130
|
+
clearRegistration: async () => true,
|
|
131
|
+
releaseLeases: (projectRoot) => releaseWorkspaceLeases(projectRoot, { slot })
|
|
132
|
+
});
|
|
133
|
+
result.outcomes.port = {
|
|
134
|
+
status: "kept",
|
|
135
|
+
port: project?.metroPort ?? null,
|
|
136
|
+
reason: "The workspace server is shared by all slots."
|
|
137
|
+
};
|
|
138
|
+
result.outcomes.metro = {
|
|
139
|
+
status: "skipped",
|
|
140
|
+
reason: "The workspace server is shared by all slots."
|
|
141
|
+
};
|
|
142
|
+
result.summary = summarize(root, result.outcomes, result.ok);
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
async function stopWorkspace({ root, project = void 0, state = void 0, collectors = void 0, signalCollector = (pid) => process.kill(pid, "SIGTERM"), verifyCollector = verifyCollectorOwnership, clearCollectors = clearCollectorState, isAlive = pidExists, killGroup = killMetroTree, inspectIdentity = inspectProcessIdentity, waitForDeath = void 0, waitMs = DEFAULT_WAIT_MS, resolveMetro = resolveProjectMetro, teardownIos = teardownOwnedIosSim, teardownAvd = teardownOwnedAvd, remoteDevice = void 0, teardownRemoteSession = defaultTeardownRemoteSession, metroTunnel = void 0, stopMetroTunnel = stopTunnel, releaseLeases = releaseWorkspaceLeases, freePort = defaultFreePort, clearRegistration = defaultClearRegistration, clearState = clearSupervisorState, report = (line) => console.error(line) }) {
|
|
105
146
|
const proj = project === void 0 ? getProject(root) : project;
|
|
106
147
|
const sup = state === void 0 ? readSupervisorState(root) : state;
|
|
107
148
|
const collectorRecords = collectors === void 0 ? readCollectorState(root) : collectors;
|
|
@@ -235,7 +276,7 @@ async function runStop({ root, project = void 0, state = void 0, collectors = vo
|
|
|
235
276
|
teardownAvd,
|
|
236
277
|
report
|
|
237
278
|
});
|
|
238
|
-
if (
|
|
279
|
+
if (Object.values(outcomes.device).some((device) => device?.status === "failed")) ok = false;
|
|
239
280
|
}
|
|
240
281
|
const remote = remoteDevice === void 0 ? readRemoteSession(root) : remoteDevice;
|
|
241
282
|
const sessionId = typeof remote?.sessionId === "string" ? remote.sessionId : null;
|
|
@@ -461,34 +502,38 @@ function shutDownDevices(project, { teardownIos, teardownAvd, report }) {
|
|
|
461
502
|
ios: null,
|
|
462
503
|
android: null
|
|
463
504
|
};
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
505
|
+
for (const { slot, platforms } of projectDeviceSlots(project)) {
|
|
506
|
+
const iosKey = slot === "default" ? "ios" : `ios:${slot}`;
|
|
507
|
+
const androidKey = slot === "default" ? "android" : `android:${slot}`;
|
|
508
|
+
const ios = platforms.ios;
|
|
509
|
+
const iosUdid = ios?.deviceUdid;
|
|
510
|
+
const iosName = ios?.deviceName;
|
|
511
|
+
if (iosUdid) {
|
|
512
|
+
if (!ios?.owned) {
|
|
513
|
+
device[iosKey] = {
|
|
514
|
+
status: "skipped",
|
|
515
|
+
kind: "not-owned",
|
|
516
|
+
label: iosUdid,
|
|
517
|
+
reason: "Stim does not own this device"
|
|
518
|
+
};
|
|
519
|
+
report(chalk.dim(phaseLine("device", `${iosUdid} is not Stim-owned, leaving it running`)));
|
|
520
|
+
} else device[iosKey] = reportDevice(iosUdid, teardownIos(iosUdid, {
|
|
521
|
+
del: false,
|
|
522
|
+
label: iosName
|
|
523
|
+
}), report);
|
|
524
|
+
}
|
|
525
|
+
const android = platforms.android;
|
|
526
|
+
if (android?.avdName) {
|
|
527
|
+
if (!android.owned) {
|
|
528
|
+
device[androidKey] = {
|
|
529
|
+
status: "skipped",
|
|
530
|
+
kind: "not-owned",
|
|
531
|
+
label: android.avdName,
|
|
532
|
+
reason: "Stim does not own this device"
|
|
533
|
+
};
|
|
534
|
+
report(chalk.dim(phaseLine("device", `${android.avdName} is not Stim-owned, leaving it running`)));
|
|
535
|
+
} else device[androidKey] = reportDevice(android.avdName, teardownAvd(android.avdName, { del: false }), report);
|
|
536
|
+
}
|
|
492
537
|
}
|
|
493
538
|
return device;
|
|
494
539
|
}
|
|
@@ -539,7 +584,7 @@ function summarize(root, outcomes, ok) {
|
|
|
539
584
|
if (outcomes.metro.status === "not-managed") parts.push(`external server on port ${outcomes.metro.port} left alone`);
|
|
540
585
|
if (outcomes.metro.status === "refused") parts.push(`port ${outcomes.metro.port} refused`);
|
|
541
586
|
if (outcomes.metro.status === "failed") parts.push(`port ${outcomes.metro.port} could not be freed`);
|
|
542
|
-
const devicesByPlatform =
|
|
587
|
+
const devicesByPlatform = Object.entries(outcomes.device).filter(([key]) => key !== "remote");
|
|
543
588
|
for (const [platform, o] of devicesByPlatform) {
|
|
544
589
|
if (!o) continue;
|
|
545
590
|
if (o.status === "shut-down") parts.push(`${platform} ${o.label} shut down`);
|
|
@@ -571,13 +616,19 @@ async function defaultClearRegistration(root, expected) {
|
|
|
571
616
|
}
|
|
572
617
|
}
|
|
573
618
|
function stopCommand(program) {
|
|
574
|
-
program.command("stop").description("The inverse of `start`: halt this workspace's supervisor, shut the owned device down (never deleted), and free the reserved port. Non-destructive -- the device stays assigned, so coming back costs a boot. Acts on the current workspace.").option("--json", "print the per-step outcomes as JSON").action(async (opts) => {
|
|
619
|
+
program.command("stop").description("The inverse of `start`: halt this workspace's supervisor, shut the owned device down (never deleted), and free the reserved port. Non-destructive -- the device stays assigned, so coming back costs a boot. Acts on the current workspace.").option("--slot <name>", "Stop only this device slot, keeping the shared server running", validateDeviceSlot).option("--json", "print the per-step outcomes as JSON").action(async (opts) => {
|
|
575
620
|
const root = findProjectRoot(process.cwd());
|
|
576
621
|
if (!root) {
|
|
577
622
|
console.error(chalk.red("Not inside a project (no package.json found above the current directory)."));
|
|
578
623
|
process.exit(1);
|
|
579
624
|
}
|
|
580
|
-
const { ok, outcomes, summary } = await
|
|
625
|
+
const { ok, outcomes, summary } = await withWorkspaceProcessLock(workspaceDir(root), "native-run", () => runStop({
|
|
626
|
+
root,
|
|
627
|
+
slot: opts.slot
|
|
628
|
+
}), {
|
|
629
|
+
external: true,
|
|
630
|
+
waitMs: 18e5
|
|
631
|
+
});
|
|
581
632
|
if (opts.json) console.log(JSON.stringify({
|
|
582
633
|
root,
|
|
583
634
|
ok,
|
|
@@ -13,12 +13,11 @@ interface WorkspaceState {
|
|
|
13
13
|
supervisor?: Record<string, unknown>;
|
|
14
14
|
collectors?: Record<string, unknown>;
|
|
15
15
|
lastBuild?: Record<string, unknown>;
|
|
16
|
-
launches?:
|
|
16
|
+
launches?: Record<string, WorkspaceLaunchRecord>;
|
|
17
17
|
remoteDevice?: Record<string, unknown>;
|
|
18
18
|
metroTunnel?: Record<string, unknown>;
|
|
19
19
|
[key: string]: unknown;
|
|
20
20
|
}
|
|
21
|
-
type WorkspaceLaunchPlatform = "ios" | "android";
|
|
22
21
|
interface WorkspaceLaunchRecord {
|
|
23
22
|
appId: string;
|
|
24
23
|
deviceId: string;
|
package/dist/supervisor-run.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { T as captureProcessToken, a as clearSupervisor, x as setSupervisor } from "./config-
|
|
2
|
-
import { r as createNdjsonWriter } from "./ndjson-
|
|
3
|
-
import { D as workspaceLogsDir, _ as writeWorkspaceState, h as writePidFile, l as readPidFile, m as withWorkspaceStateLock, n as MODE_EXPO, p as readWorkspaceState, r as clearExpoMetroTunnel, s as clearWorkspaceSupervisor, t as MODE_BARE } from "./state-
|
|
4
|
-
import { i as detectIsExpo } from "./project-
|
|
1
|
+
import { T as captureProcessToken, a as clearSupervisor, x as setSupervisor } from "./config-CcefMY2Q.mjs";
|
|
2
|
+
import { r as createNdjsonWriter } from "./ndjson-BZwI1NBv.mjs";
|
|
3
|
+
import { D as workspaceLogsDir, _ as writeWorkspaceState, h as writePidFile, l as readPidFile, m as withWorkspaceStateLock, n as MODE_EXPO, p as readWorkspaceState, r as clearExpoMetroTunnel, s as clearWorkspaceSupervisor, t as MODE_BARE } from "./state-B3XA2wp2.mjs";
|
|
4
|
+
import { i as detectIsExpo } from "./project-fKmuIaMI.mjs";
|
|
5
5
|
import { t as describeError } from "./errors-B6W7FkxQ.mjs";
|
|
6
6
|
import { existsSync, realpathSync } from "node:fs";
|
|
7
7
|
import { isAbsolute, join, resolve } from "node:path";
|
|
@@ -97,7 +97,7 @@ async function runSupervisor({ root, port, tunnel = false, isExpo = detectIsExpo
|
|
|
97
97
|
};
|
|
98
98
|
let server;
|
|
99
99
|
try {
|
|
100
|
-
server = await (mode === "expo-child" ? startExpo || (await import("./server-expo-
|
|
100
|
+
server = await (mode === "expo-child" ? startExpo || (await import("./server-expo-44em5Pmg.mjs")).startExpoServer : startBare || (await import("./server-bare-DEzPZLvf.mjs")).startBareServer)({
|
|
101
101
|
root,
|
|
102
102
|
port,
|
|
103
103
|
logsDir,
|