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,24 +1,33 @@
|
|
|
1
1
|
import { n as __exportAll, r as __reExport } from "./rolldown-runtime-BsOwBuO_.mjs";
|
|
2
|
-
import { t as getExecutor } from "./exec-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { dirname
|
|
2
|
+
import { t as getExecutor } from "./exec-jIAlgilk.mjs";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { InvalidArgumentError } from "commander";
|
|
5
|
+
import { existsSync as existsSync$1, lstatSync as lstatSync$1, mkdirSync as mkdirSync$1, readdirSync as readdirSync$1, readlinkSync, renameSync as renameSync$1, statSync as statSync$1, unlinkSync as unlinkSync$1, writeFileSync as writeFileSync$1 } from "fs";
|
|
6
|
+
import { dirname, isAbsolute, join, normalize, parse, sep } from "path";
|
|
7
7
|
import { configDir, withDirLock } from "@stim-cli/core";
|
|
8
|
+
import { join as join$1 } from "node:path";
|
|
8
9
|
//#region src/devices/device-slots.ts
|
|
9
10
|
const DEFAULT_DEVICE_SLOT = "default";
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
const DEVICE_SLOT_RULE = "A device slot must be 1-64 letters, digits, underscores or hyphens, starting with a letter or digit.";
|
|
12
|
+
function isDeviceSlot(slot) {
|
|
13
|
+
return /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(slot) && ![
|
|
12
14
|
"constructor",
|
|
13
15
|
"prototype",
|
|
14
16
|
"__proto__"
|
|
15
|
-
].includes(slot)
|
|
16
|
-
|
|
17
|
+
].includes(slot);
|
|
18
|
+
}
|
|
19
|
+
function validateDeviceSlot(slot = "default") {
|
|
20
|
+
if (!isDeviceSlot(slot)) {
|
|
21
|
+
const error = /* @__PURE__ */ new Error(DEVICE_SLOT_RULE);
|
|
17
22
|
Object.assign(error, { code: "STIM_BAD_ARG" });
|
|
18
23
|
throw error;
|
|
19
24
|
}
|
|
20
25
|
return slot;
|
|
21
26
|
}
|
|
27
|
+
function parseDeviceSlotOption(slot) {
|
|
28
|
+
if (!isDeviceSlot(slot)) throw new InvalidArgumentError(DEVICE_SLOT_RULE);
|
|
29
|
+
return slot;
|
|
30
|
+
}
|
|
22
31
|
function deviceSlotPlatforms(project, slot = DEFAULT_DEVICE_SLOT) {
|
|
23
32
|
validateDeviceSlot(slot);
|
|
24
33
|
if (slot === DEFAULT_DEVICE_SLOT) return project?.platforms;
|
|
@@ -98,26 +107,26 @@ const WINDOWS = process.platform === "win32";
|
|
|
98
107
|
const DRIVE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
99
108
|
function volumeRootFor(path) {
|
|
100
109
|
const normalized = normalize(String(path));
|
|
101
|
-
if (WINDOWS) return parse
|
|
110
|
+
if (WINDOWS) return parse(normalized).root.replace(/^[a-z]:/, (drive) => drive.toUpperCase());
|
|
102
111
|
const m = normalized.match(/^\/volumes\/([^/]+)/i);
|
|
103
112
|
return m ? `/Volumes/${m[1]}` : "/";
|
|
104
113
|
}
|
|
105
114
|
function resolveWorkspaceRealish(workspacePath) {
|
|
106
115
|
const raw = String(workspacePath);
|
|
107
|
-
if (!isAbsolute
|
|
116
|
+
if (!isAbsolute(raw)) return null;
|
|
108
117
|
let current = raw;
|
|
109
118
|
const MAX_HOPS = 40;
|
|
110
119
|
for (let hops = 0; hops < MAX_HOPS; hops++) {
|
|
111
120
|
const normalized = normalize(current);
|
|
112
|
-
const root = parse
|
|
113
|
-
const segments = normalized.slice(root.length).split(sep
|
|
114
|
-
let prefix = root.endsWith(sep
|
|
121
|
+
const root = parse(normalized).root;
|
|
122
|
+
const segments = normalized.slice(root.length).split(sep).filter(Boolean);
|
|
123
|
+
let prefix = root.endsWith(sep) ? root.slice(0, -sep.length) : root;
|
|
115
124
|
let followedSymlink = false;
|
|
116
125
|
for (const segment of segments) {
|
|
117
|
-
prefix += `${sep
|
|
126
|
+
prefix += `${sep}${segment}`;
|
|
118
127
|
let st;
|
|
119
128
|
try {
|
|
120
|
-
st = lstatSync(prefix);
|
|
129
|
+
st = lstatSync$1(prefix);
|
|
121
130
|
} catch (err) {
|
|
122
131
|
if (err && err.code === "ENOENT") return normalized;
|
|
123
132
|
return null;
|
|
@@ -129,7 +138,7 @@ function resolveWorkspaceRealish(workspacePath) {
|
|
|
129
138
|
} catch {
|
|
130
139
|
return null;
|
|
131
140
|
}
|
|
132
|
-
current = `${isAbsolute
|
|
141
|
+
current = `${isAbsolute(target) ? target : normalize(join(dirname(prefix), target))}${normalized.slice(prefix.length)}`;
|
|
133
142
|
followedSymlink = true;
|
|
134
143
|
break;
|
|
135
144
|
}
|
|
@@ -144,7 +153,7 @@ function isRealMount(entryDev, rootDev) {
|
|
|
144
153
|
function listWindowsVolumeRoots(statFn) {
|
|
145
154
|
const roots = [];
|
|
146
155
|
for (const letter of DRIVE_LETTERS) {
|
|
147
|
-
const root = `${letter}:${sep
|
|
156
|
+
const root = `${letter}:${sep}`;
|
|
148
157
|
try {
|
|
149
158
|
statFn(root);
|
|
150
159
|
} catch {
|
|
@@ -154,7 +163,7 @@ function listWindowsVolumeRoots(statFn) {
|
|
|
154
163
|
}
|
|
155
164
|
return roots;
|
|
156
165
|
}
|
|
157
|
-
function listMountedVolumes({ statFn = statSync } = {}) {
|
|
166
|
+
function listMountedVolumes({ statFn = statSync$1 } = {}) {
|
|
158
167
|
if (WINDOWS) return listWindowsVolumeRoots(statFn);
|
|
159
168
|
const roots = ["/"];
|
|
160
169
|
let rootDev;
|
|
@@ -164,8 +173,8 @@ function listMountedVolumes({ statFn = statSync } = {}) {
|
|
|
164
173
|
return roots;
|
|
165
174
|
}
|
|
166
175
|
try {
|
|
167
|
-
for (const name of readdirSync("/Volumes")) {
|
|
168
|
-
const path = join
|
|
176
|
+
for (const name of readdirSync$1("/Volumes")) {
|
|
177
|
+
const path = join("/Volumes", name);
|
|
169
178
|
let entryDev;
|
|
170
179
|
try {
|
|
171
180
|
entryDev = statFn(path).dev;
|
|
@@ -181,26 +190,29 @@ function resolveVolumeRoot(path) {
|
|
|
181
190
|
const realish = resolveWorkspaceRealish(path);
|
|
182
191
|
return realish === null ? null : volumeRootFor(realish);
|
|
183
192
|
}
|
|
184
|
-
function uncShareIsReachable(volume) {
|
|
185
|
-
if (!WINDOWS || !volume.startsWith(`${sep
|
|
193
|
+
function uncShareIsReachable(volume, statFn) {
|
|
194
|
+
if (!WINDOWS || !volume.startsWith(`${sep}${sep}`)) return false;
|
|
186
195
|
try {
|
|
187
|
-
return
|
|
196
|
+
return statFn(volume).isDirectory();
|
|
188
197
|
} catch {
|
|
189
198
|
return false;
|
|
190
199
|
}
|
|
191
200
|
}
|
|
192
|
-
function isOnMountedVolume(path, mountedVolumes) {
|
|
201
|
+
function isOnMountedVolume(path, mountedVolumes, { statFn = statSync$1 } = {}) {
|
|
193
202
|
const mounted = new Set(mountedVolumes || listMountedVolumes());
|
|
194
203
|
const volume = resolveVolumeRoot(path);
|
|
195
204
|
if (volume === null) return false;
|
|
196
|
-
return mounted.has(volume) || uncShareIsReachable(volume);
|
|
205
|
+
return mounted.has(volume) || uncShareIsReachable(volume, statFn);
|
|
197
206
|
}
|
|
198
207
|
function directorySize(dir, { timeoutMs } = {}) {
|
|
208
|
+
return measuredDirectorySize(dir, { timeoutMs }) ?? 0;
|
|
209
|
+
}
|
|
210
|
+
function measuredDirectorySize(dir, { timeoutMs } = {}) {
|
|
199
211
|
let out;
|
|
200
212
|
try {
|
|
201
213
|
out = getExecutor().runFile("du", ["-sk", dir], { timeoutMs });
|
|
202
214
|
} catch {
|
|
203
|
-
return
|
|
215
|
+
return null;
|
|
204
216
|
}
|
|
205
217
|
if (!out) return 0;
|
|
206
218
|
const kb = parseInt(out.split(/\s+/)[0] ?? "", 10);
|
|
@@ -212,6 +224,22 @@ function formatBytes(bytes) {
|
|
|
212
224
|
return `${Math.round(bytes / 1024)}K`;
|
|
213
225
|
}
|
|
214
226
|
//#endregion
|
|
227
|
+
//#region src/json-file.ts
|
|
228
|
+
function readJsonFile(path) {
|
|
229
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
230
|
+
}
|
|
231
|
+
function isJsonObject(value) {
|
|
232
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
233
|
+
}
|
|
234
|
+
function readJsonObject(path) {
|
|
235
|
+
try {
|
|
236
|
+
const value = readJsonFile(path);
|
|
237
|
+
return isJsonObject(value) ? value : null;
|
|
238
|
+
} catch {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//#endregion
|
|
215
243
|
//#region src/ownership-claim.ts
|
|
216
244
|
var ownership_claim_exports = /* @__PURE__ */ __exportAll({});
|
|
217
245
|
import * as import__stim_cli_core_ownership_claim from "@stim-cli/core/ownership-claim";
|
|
@@ -219,7 +247,7 @@ __reExport(ownership_claim_exports, import__stim_cli_core_ownership_claim);
|
|
|
219
247
|
//#endregion
|
|
220
248
|
//#region src/devices/avd-claim.ts
|
|
221
249
|
function acquireAvdClaim(avdName) {
|
|
222
|
-
const root = join(configDir(), "avd-locks", `${encodeURIComponent(avdName.toLowerCase())}.lock`);
|
|
250
|
+
const root = join$1(configDir(), "avd-locks", `${encodeURIComponent(avdName.toLowerCase())}.lock`);
|
|
223
251
|
const label = `AVD ${avdName}`;
|
|
224
252
|
const attempt = (0, ownership_claim_exports.tryAcquireClaim)({
|
|
225
253
|
root,
|
|
@@ -243,18 +271,31 @@ __reExport(process_identity_exports, import__stim_cli_core_process_identity);
|
|
|
243
271
|
//#endregion
|
|
244
272
|
//#region src/workspace/config.ts
|
|
245
273
|
function getConfigDir() {
|
|
246
|
-
return
|
|
274
|
+
return configDir();
|
|
275
|
+
}
|
|
276
|
+
function refuseRelativeStimPaths(env = process.env) {
|
|
277
|
+
for (const name of [
|
|
278
|
+
"STIM_HOME",
|
|
279
|
+
"STIM_BUILD_CACHE",
|
|
280
|
+
"STIM_METRO_CACHE"
|
|
281
|
+
]) {
|
|
282
|
+
const value = env[name];
|
|
283
|
+
if (!value || isAbsolute(value)) continue;
|
|
284
|
+
const error = /* @__PURE__ */ new Error(`${name}=${value} is not an absolute path. Set it to an absolute path, or unset it to use the default.`);
|
|
285
|
+
error.code = "STIM_RELATIVE_PATH";
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
247
288
|
}
|
|
248
289
|
function getConfigPath() {
|
|
249
|
-
return join
|
|
290
|
+
return join(getConfigDir(), "config.json");
|
|
250
291
|
}
|
|
251
292
|
function ensureDir() {
|
|
252
293
|
const dir = getConfigDir();
|
|
253
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
294
|
+
if (!existsSync$1(dir)) mkdirSync$1(dir, { recursive: true });
|
|
254
295
|
}
|
|
255
296
|
const LOCK_DIR_NAME = "config.lock";
|
|
256
297
|
function lockPath() {
|
|
257
|
-
return join
|
|
298
|
+
return join(getConfigDir(), LOCK_DIR_NAME);
|
|
258
299
|
}
|
|
259
300
|
function withConfigLock(fn) {
|
|
260
301
|
return withDirLock(lockPath(), fn, { ensureParent: ensureDir });
|
|
@@ -270,40 +311,50 @@ function configCorrupt(reason, path = getConfigPath()) {
|
|
|
270
311
|
}
|
|
271
312
|
function loadConfig() {
|
|
272
313
|
const p = getConfigPath();
|
|
273
|
-
if (!existsSync(p)) return null;
|
|
274
|
-
|
|
314
|
+
if (!existsSync$1(p)) return null;
|
|
315
|
+
let parsed;
|
|
275
316
|
try {
|
|
276
|
-
|
|
317
|
+
parsed = readJsonFile(p);
|
|
277
318
|
} catch (err) {
|
|
319
|
+
if (!(err instanceof SyntaxError)) throw err;
|
|
278
320
|
throw configCorrupt(`is not valid JSON: ${err.message}`, p);
|
|
279
321
|
}
|
|
322
|
+
return configFromJson(parsed, p);
|
|
280
323
|
}
|
|
281
|
-
function
|
|
282
|
-
|
|
324
|
+
function configFromJson(value, path) {
|
|
325
|
+
if (!isJsonObject(value)) throw configCorrupt(`is not a JSON object: ${JSON.stringify(value)}`, path);
|
|
326
|
+
return {
|
|
327
|
+
...value,
|
|
328
|
+
projects: registryFromJson(value, "projects", path),
|
|
329
|
+
repos: registryFromJson(value, "repos", path)
|
|
330
|
+
};
|
|
283
331
|
}
|
|
284
332
|
/**
|
|
285
333
|
* An array or scalar container swallows every write silently: `JSON.stringify` drops a string key set on
|
|
286
|
-
* an array, so the record is gone by the time the file is written. Absent is
|
|
334
|
+
* an array, so the record is gone by the time the file is written. Absent or null is read as empty; an
|
|
335
|
+
* unusable container or entry is refused.
|
|
287
336
|
*/
|
|
288
|
-
function
|
|
289
|
-
const value =
|
|
290
|
-
if (value === void 0 || value === null) {
|
|
291
|
-
|
|
292
|
-
|
|
337
|
+
function registryFromJson(config, key, path) {
|
|
338
|
+
const value = config[key];
|
|
339
|
+
if (value === void 0 || value === null) return {};
|
|
340
|
+
if (!isJsonObject(value)) throw configCorrupt(`has a ${key} that is not an object: ${JSON.stringify(value)}`, path);
|
|
341
|
+
const registry = {};
|
|
342
|
+
for (const [name, entry] of Object.entries(value)) {
|
|
343
|
+
if (!isJsonObject(entry)) throw configCorrupt(`has a ${key} entry ${JSON.stringify(name)} that is not an object: ${JSON.stringify(entry)}`, path);
|
|
344
|
+
registry[name] = entry;
|
|
293
345
|
}
|
|
294
|
-
|
|
295
|
-
return false;
|
|
346
|
+
return registry;
|
|
296
347
|
}
|
|
297
348
|
function saveConfig(config) {
|
|
298
349
|
ensureDir();
|
|
299
350
|
const target = getConfigPath();
|
|
300
351
|
const tmp = `${target}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
301
|
-
writeFileSync(tmp, JSON.stringify(config, null, 2) + "\n");
|
|
352
|
+
writeFileSync$1(tmp, JSON.stringify(config, null, 2) + "\n");
|
|
302
353
|
try {
|
|
303
|
-
renameSync(tmp, target);
|
|
354
|
+
renameSync$1(tmp, target);
|
|
304
355
|
} catch (err) {
|
|
305
356
|
try {
|
|
306
|
-
unlinkSync(tmp);
|
|
357
|
+
unlinkSync$1(tmp);
|
|
307
358
|
} catch {}
|
|
308
359
|
throw err;
|
|
309
360
|
}
|
|
@@ -313,14 +364,10 @@ function ensureConfig() {
|
|
|
313
364
|
return withConfigLock(() => {
|
|
314
365
|
const existing = loadConfig();
|
|
315
366
|
if (existing) {
|
|
316
|
-
let changed = false;
|
|
317
|
-
if (adoptContainer(existing, "projects")) changed = true;
|
|
318
|
-
if (adoptContainer(existing, "repos")) changed = true;
|
|
319
367
|
if (existing.version !== CONFIG_VERSION) {
|
|
320
368
|
existing.version = CONFIG_VERSION;
|
|
321
|
-
|
|
369
|
+
saveConfig(existing);
|
|
322
370
|
}
|
|
323
|
-
if (changed) saveConfig(existing);
|
|
324
371
|
return existing;
|
|
325
372
|
}
|
|
326
373
|
const fresh = {
|
|
@@ -336,7 +383,7 @@ function getProject(projectPath) {
|
|
|
336
383
|
return loadConfig()?.projects?.[projectPath] || null;
|
|
337
384
|
}
|
|
338
385
|
function requireAbsoluteProjectPath(projectPath) {
|
|
339
|
-
if (isAbsolute
|
|
386
|
+
if (isAbsolute(projectPath)) return;
|
|
340
387
|
throw new Error(`Project key "${projectPath}" is not an absolute path. The registry is keyed by the realpath of a workspace root, so a relative key can never resolve.`);
|
|
341
388
|
}
|
|
342
389
|
function upsertProject(projectPath, fields) {
|
|
@@ -378,6 +425,15 @@ function claimMetroPort(projectPath, port) {
|
|
|
378
425
|
return port;
|
|
379
426
|
});
|
|
380
427
|
}
|
|
428
|
+
function releaseMetroPort(projectPath, port) {
|
|
429
|
+
withConfigLock(() => {
|
|
430
|
+
const cfg = loadConfig();
|
|
431
|
+
const project = cfg?.projects?.[projectPath];
|
|
432
|
+
if (!cfg || project?.metroPort !== port) return;
|
|
433
|
+
project.metroPort = null;
|
|
434
|
+
saveConfig(cfg);
|
|
435
|
+
});
|
|
436
|
+
}
|
|
381
437
|
function setDevice(projectPath, platform, deviceFields, slot = "default") {
|
|
382
438
|
requireAbsoluteProjectPath(projectPath);
|
|
383
439
|
withConfigLock(() => {
|
|
@@ -456,6 +512,80 @@ function getProjectSettings(projectPath) {
|
|
|
456
512
|
function getRepoSettings(gitCommonDir) {
|
|
457
513
|
return loadConfig()?.repos?.[gitCommonDir]?.settings || {};
|
|
458
514
|
}
|
|
515
|
+
function targetSettings(cfg, target, create) {
|
|
516
|
+
if (target.scope === "machine") return cfg;
|
|
517
|
+
if (target.scope === "workspace") {
|
|
518
|
+
if (!cfg.projects[target.projectPath]) {
|
|
519
|
+
if (!create) return null;
|
|
520
|
+
cfg.projects[target.projectPath] = {
|
|
521
|
+
metroPort: null,
|
|
522
|
+
platforms: {}
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
const project = cfg.projects[target.projectPath];
|
|
526
|
+
if (!project.settings && create) project.settings = {};
|
|
527
|
+
return project.settings ?? null;
|
|
528
|
+
}
|
|
529
|
+
if (!cfg.repos[target.gitCommonDir]) {
|
|
530
|
+
if (!create) return null;
|
|
531
|
+
cfg.repos[target.gitCommonDir] = {};
|
|
532
|
+
}
|
|
533
|
+
const repo = cfg.repos[target.gitCommonDir];
|
|
534
|
+
if (!repo.settings && create) repo.settings = {};
|
|
535
|
+
return repo.settings ?? null;
|
|
536
|
+
}
|
|
537
|
+
function writeConfigSetting(target, dottedKey, value) {
|
|
538
|
+
if (target.scope === "workspace") requireAbsoluteProjectPath(target.projectPath);
|
|
539
|
+
return withConfigLock(() => {
|
|
540
|
+
const cfg = value === void 0 ? loadConfig() : ensureConfig();
|
|
541
|
+
const settings = cfg ? targetSettings(cfg, target, value !== void 0) : null;
|
|
542
|
+
if (!cfg || !settings) return false;
|
|
543
|
+
if (value === void 0) {
|
|
544
|
+
if (!deleteNested(settings, dottedKey)) return false;
|
|
545
|
+
} else writeNested(settings, dottedKey, value);
|
|
546
|
+
saveConfig(cfg);
|
|
547
|
+
return true;
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
function writeNested(obj, dottedKey, value) {
|
|
551
|
+
const keys = dottedKey.split(".");
|
|
552
|
+
let cur = obj;
|
|
553
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
554
|
+
const k = keys[i];
|
|
555
|
+
if (k === void 0) continue;
|
|
556
|
+
const next = cur[k];
|
|
557
|
+
if (typeof next !== "object" || next === null) cur[k] = {};
|
|
558
|
+
cur = cur[k];
|
|
559
|
+
}
|
|
560
|
+
const leaf = keys[keys.length - 1];
|
|
561
|
+
if (leaf !== void 0) cur[leaf] = value;
|
|
562
|
+
}
|
|
563
|
+
function deleteNested(obj, dottedKey) {
|
|
564
|
+
const keys = dottedKey.split(".");
|
|
565
|
+
const chain = [obj];
|
|
566
|
+
let cur = obj;
|
|
567
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
568
|
+
const k = keys[i];
|
|
569
|
+
if (k === void 0) return false;
|
|
570
|
+
const next = cur[k];
|
|
571
|
+
if (next == null || typeof next !== "object") return false;
|
|
572
|
+
cur = next;
|
|
573
|
+
chain.push(cur);
|
|
574
|
+
}
|
|
575
|
+
const leaf = keys[keys.length - 1];
|
|
576
|
+
if (leaf === void 0) return false;
|
|
577
|
+
if (!(leaf in cur)) return false;
|
|
578
|
+
delete cur[leaf];
|
|
579
|
+
for (let i = chain.length - 2; i >= 0; i--) {
|
|
580
|
+
const parent = chain[i];
|
|
581
|
+
const key = keys[i];
|
|
582
|
+
const child = chain[i + 1];
|
|
583
|
+
if (parent === void 0 || key === void 0 || child === void 0) break;
|
|
584
|
+
if (Object.keys(child).length === 0) delete parent[key];
|
|
585
|
+
else break;
|
|
586
|
+
}
|
|
587
|
+
return true;
|
|
588
|
+
}
|
|
459
589
|
function isPathPrefix(prefix, path) {
|
|
460
590
|
const head = comparablePath(prefix);
|
|
461
591
|
const candidate = comparablePath(path);
|
|
@@ -463,7 +593,7 @@ function isPathPrefix(prefix, path) {
|
|
|
463
593
|
return candidate.startsWith(head.endsWith("/") ? head : `${head}/`);
|
|
464
594
|
}
|
|
465
595
|
function comparablePath(path) {
|
|
466
|
-
return sep
|
|
596
|
+
return sep === "/" ? path : path.replaceAll(sep, "/");
|
|
467
597
|
}
|
|
468
598
|
function findEnclosingWorktreeRoot(projectPath) {
|
|
469
599
|
const cfg = loadConfig();
|
|
@@ -489,7 +619,7 @@ function allConsolePortsAndSerials({ isMounted = isOnMountedVolume } = {}) {
|
|
|
489
619
|
};
|
|
490
620
|
if (!cfg) return result;
|
|
491
621
|
for (const [path, proj] of Object.entries(cfg.projects || {})) {
|
|
492
|
-
if (!existsSync(path) && isMounted(path)) continue;
|
|
622
|
+
if (!existsSync$1(path) && isMounted(path)) continue;
|
|
493
623
|
for (const { platforms } of projectDeviceSlots(proj)) {
|
|
494
624
|
const android = platforms.android;
|
|
495
625
|
if (typeof android?.consolePort === "number") result.androidConsolePorts.push(android.consolePort);
|
|
@@ -499,4 +629,4 @@ function allConsolePortsAndSerials({ isMounted = isOnMountedVolume } = {}) {
|
|
|
499
629
|
return result;
|
|
500
630
|
}
|
|
501
631
|
//#endregion
|
|
502
|
-
export {
|
|
632
|
+
export { withDirLock as A, assignSlotDevice as B, setSupervisor as C, process_identity_exports as D, writeConfigSetting as E, formatBytes as F, parseDeviceSlotOption as G, deviceSlotKey as H, isOnMountedVolume as I, validateDeviceSlot as J, projectDeviceSlots as K, listMountedVolumes as L, readJsonFile as M, readJsonObject as N, acquireAvdClaim as O, directorySize as P, measuredDirectorySize as R, setDevice as S, withConfigLock as T, deviceSlotPlatforms as U, deviceSlotFileKey as V, parseDeviceSlotKey as W, refuseRelativeStimPaths as _, clearSupervisor as a, removeProject as b, findEnclosingWorktreeRoot as c, getConfigPath as d, getProject as f, loadConfig as g, isPathPrefix as h, clearDevice as i, isJsonObject as j, ownership_claim_exports as k, getConcurrencyLimits as l, getRepoSettings as m, allMetroPorts as n, configCorruptRepair as o, getProjectSettings as p, removeSlotDevice as q, claimMetroPort as r, ensureConfig as s, allConsolePortsAndSerials as t, getConfigDir as u, releaseAndroidConsolePort as v, upsertProject as w, saveConfig as x, releaseMetroPort as y, volumeRootFor as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import {
|
|
1
|
+
import { t as getExecutor } from "./exec-jIAlgilk.mjs";
|
|
2
|
+
import { _ as repoRoot } from "./worktree-R_cUlE7s.mjs";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { dirname, join, relative } from "node:path";
|
|
5
5
|
//#region src/dependency-state.ts
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-
|
|
3
|
-
import {
|
|
1
|
+
import { t as getExecutor } from "./exec-jIAlgilk.mjs";
|
|
2
|
+
import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
|
|
3
|
+
import { n as spawnDeclared } from "./spawn-claims-Dn3C_N6w.mjs";
|
|
4
|
+
import { d as startBuildHeartbeat, m as bundlerPin, n as HEARTBEAT_INTERVAL_MS } from "./xcode-BZqyxh3e.mjs";
|
|
4
5
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
6
|
import { delimiter, dirname, join, relative, resolve, sep } from "node:path";
|
|
6
7
|
import { homedir } from "node:os";
|
|
7
8
|
//#region src/engine/deps.ts
|
|
8
9
|
const DEPS_ERROR = "STIM_DEPS_FAILED";
|
|
10
|
+
const TRANSCRIPT_LINES = 2e3;
|
|
9
11
|
const MAX_POD_DIAGNOSTIC_LINES = 15;
|
|
10
12
|
const POD_MARKER = /^\[!\]/;
|
|
11
13
|
const POD_CONTINUATION = /^\s+\S/;
|
|
@@ -182,6 +184,7 @@ async function runCaptured(ctx) {
|
|
|
182
184
|
const msg = stripAnsi(String(line)).trimEnd();
|
|
183
185
|
if (!msg.trim()) return;
|
|
184
186
|
transcript.push(msg);
|
|
187
|
+
if (transcript.length > TRANSCRIPT_LINES) transcript.splice(TRANSCRIPT_LINES / 2, 1);
|
|
185
188
|
ctx.logWriter?.write?.({
|
|
186
189
|
src: "build",
|
|
187
190
|
level: "debug",
|
|
@@ -192,7 +195,7 @@ async function runCaptured(ctx) {
|
|
|
192
195
|
};
|
|
193
196
|
let child;
|
|
194
197
|
try {
|
|
195
|
-
child = ctx.spawn(ctx.cmd, ctx.args, {
|
|
198
|
+
child = spawnDeclared(() => ctx.spawn(ctx.cmd, ctx.args, {
|
|
196
199
|
cwd: ctx.cwd,
|
|
197
200
|
stdio: [
|
|
198
201
|
"ignore",
|
|
@@ -200,7 +203,7 @@ async function runCaptured(ctx) {
|
|
|
200
203
|
"pipe"
|
|
201
204
|
],
|
|
202
205
|
env: ctx.env
|
|
203
|
-
});
|
|
206
|
+
}));
|
|
204
207
|
} catch (error) {
|
|
205
208
|
return {
|
|
206
209
|
transcript,
|