peachsim 0.1.630 → 0.1.631

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 (89) hide show
  1. package/cli/app-fonts.ts +23 -4
  2. package/cli/bridge-flow-runner.ts +35 -28
  3. package/cli/command-registry.ts +1 -0
  4. package/cli/commands/compat.ts +11 -60
  5. package/cli/commands/control.ts +12 -5
  6. package/cli/commands/detect.ts +289 -26
  7. package/cli/commands/inspect/core.ts +1 -1
  8. package/cli/commands/inspect.ts +4 -0
  9. package/cli/commands/maestro.ts +3 -1
  10. package/cli/commands/project-report.ts +386 -0
  11. package/cli/commands/projectReportContract.ts +42 -0
  12. package/cli/commands/report-issue.ts +38 -54
  13. package/cli/commands/setup.ts +6 -4
  14. package/cli/commands/telemetry.ts +8 -3
  15. package/cli/commands/test.ts +347 -134
  16. package/cli/main.ts +11 -1
  17. package/cli/outbound-endpoints.ts +2 -1
  18. package/cli/privacy.ts +1 -2
  19. package/cli/runtime-diagnostics.ts +51 -0
  20. package/cli/telemetry.ts +78 -7
  21. package/detox/index.ts +3 -8
  22. package/dist-lib/agent-daemon-client.cjs +1 -1
  23. package/dist-lib/agent-events.cjs +1 -1
  24. package/dist-lib/agent-identity.cjs +1 -1
  25. package/dist-lib/agent-sessions.cjs +1 -1
  26. package/dist-lib/attached-projects.cjs +1 -1
  27. package/dist-lib/auth/shared-session.cjs +1 -1
  28. package/dist-lib/backend-origin.cjs +1 -1
  29. package/dist-lib/beta.cjs +1 -1
  30. package/dist-lib/beta.mjs +1 -1
  31. package/dist-lib/bridge-constants.cjs +1 -1
  32. package/dist-lib/bridge-contract-input.cjs +1 -1
  33. package/dist-lib/bridge-contract-input.mjs +1 -1
  34. package/dist-lib/bridge-contract.cjs +1 -1
  35. package/dist-lib/bridge-contract.mjs +1 -1
  36. package/dist-lib/capture-contract.cjs +1 -1
  37. package/dist-lib/capture-contract.mjs +1 -1
  38. package/dist-lib/cli-constants.cjs +1 -1
  39. package/dist-lib/cloud-contract.cjs +1 -1
  40. package/dist-lib/cloud-contract.mjs +1 -1
  41. package/dist-lib/cloud-test-args.cjs +1 -1
  42. package/dist-lib/cloud-test-args.mjs +1 -1
  43. package/dist-lib/cloud.cjs +1 -1
  44. package/dist-lib/cloud.mjs +1 -1
  45. package/dist-lib/config.cjs +1 -1
  46. package/dist-lib/detox/index.cjs +2 -7
  47. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  48. package/dist-lib/home-paths.cjs +8 -5
  49. package/dist-lib/host/bridge-host.cjs +110 -67
  50. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  51. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  52. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  53. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  54. package/dist-lib/host/websocket-proxy.cjs +1 -1
  55. package/dist-lib/index.cjs +5 -1
  56. package/dist-lib/jump-to-source-babel.cjs +1 -1
  57. package/dist-lib/jump-to-source-native.cjs +1 -1
  58. package/dist-lib/kotlin-host.cjs +1 -1
  59. package/dist-lib/menu.cjs +11 -1
  60. package/dist-lib/menu.mjs +11 -1
  61. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  62. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  63. package/dist-lib/metro-production-bundle.cjs +1 -1
  64. package/dist-lib/metro-production-bundle.mjs +1 -1
  65. package/dist-lib/metro.cjs +1 -1
  66. package/dist-lib/native-app-identity.cjs +1 -1
  67. package/dist-lib/native-app-identity.mjs +1 -1
  68. package/dist-lib/profiles.cjs +1 -1
  69. package/dist-lib/public-brand.cjs +1 -1
  70. package/dist-lib/react-native-host-modules.cjs +1 -1
  71. package/dist-lib/react-native-host-modules.mjs +1 -1
  72. package/dist-lib/render-mode.cjs +1 -1
  73. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  74. package/dist-lib/sdk.cjs +3 -1
  75. package/dist-lib/sdk.mjs +2 -1
  76. package/dist-lib/skills.cjs +589 -268
  77. package/dist-lib/swift-compile.cjs +1 -1
  78. package/dist-lib/swift-compile.mjs +1 -1
  79. package/dist-lib/swift-package.cjs +1 -1
  80. package/dist-lib/swift-package.mjs +1 -1
  81. package/dist-lib/swift-submit.cjs +1 -1
  82. package/dist-lib/swift-submit.mjs +1 -1
  83. package/dist-lib/swift.cjs +439 -167
  84. package/dist-lib/vite-swift.cjs +1 -1
  85. package/dist-lib/vite.cjs +1 -1
  86. package/package.json +2 -1
  87. package/skills/contrast/SKILL.md +1 -0
  88. package/src/home-paths.ts +11 -9
  89. package/src/menu.ts +11 -0
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.631 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -20638,7 +20638,7 @@ function readPrivacyPreferences() {
20638
20638
  return {
20639
20639
  productAnalytics: typeof productAnalytics === "boolean" ? productAnalytics : false,
20640
20640
  crashReports: typeof crashReports === "boolean" ? crashReports : false,
20641
- configured: typeof productAnalytics === "boolean" && typeof crashReports === "boolean"
20641
+ configured: typeof productAnalytics === "boolean"
20642
20642
  };
20643
20643
  }
20644
20644
  function writePrivacyPreferences(preferences) {
@@ -20650,10 +20650,13 @@ function writePrivacyPreferences(preferences) {
20650
20650
  });
20651
20651
  }
20652
20652
  function readOrCreateAnonymousId() {
20653
- const existing = readSharedConfig().anonymousId;
20654
- if (typeof existing === "string" && existing.trim()) return existing;
20653
+ const existing = readSharedConfig().settings?.anonymousId;
20654
+ if (typeof existing === "string" && /^anon-cli-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(
20655
+ existing
20656
+ ))
20657
+ return existing;
20655
20658
  const created = `anon-cli-${(0, import_node_crypto.randomUUID)()}`;
20656
- writeSharedConfig({ anonymousId: created });
20659
+ writeSharedConfig({ settings: { anonymousId: created } });
20657
20660
  return created;
20658
20661
  }
20659
20662
  function readDefaultBox() {
@@ -22679,10 +22682,10 @@ var init_agent_host = __esm({
22679
22682
  return simId;
22680
22683
  }
22681
22684
  listenForInspect(socket, simId) {
22682
- const queue = this.inspectQueues.get(simId);
22683
- const queued = queue?.shift();
22684
- if (queued && queue) {
22685
- if (queue.length === 0) this.inspectQueues.delete(simId);
22685
+ const queue2 = this.inspectQueues.get(simId);
22686
+ const queued = queue2?.shift();
22687
+ if (queued && queue2) {
22688
+ if (queue2.length === 0) this.inspectQueues.delete(simId);
22686
22689
  return Promise.resolve(queued);
22687
22690
  }
22688
22691
  return new Promise((resolve9, reject) => {
@@ -22708,9 +22711,9 @@ var init_agent_host = __esm({
22708
22711
  listener.resolve(message);
22709
22712
  return { ok: true, queued: false, messageId: message.id };
22710
22713
  }
22711
- const queue = this.inspectQueues.get(simId) ?? [];
22712
- queue.push(message);
22713
- this.inspectQueues.set(simId, queue);
22714
+ const queue2 = this.inspectQueues.get(simId) ?? [];
22715
+ queue2.push(message);
22716
+ this.inspectQueues.set(simId, queue2);
22714
22717
  return { ok: true, queued: true, messageId: message.id };
22715
22718
  }
22716
22719
  async doStartSession(input) {
@@ -27601,13 +27604,13 @@ function embedTemplateRoot(args) {
27601
27604
  const root = template.roots[args.rootIndex];
27602
27605
  const moduleIdsByNode = /* @__PURE__ */ new Map([[root.node, args.bundleRoot.moduleId]]);
27603
27606
  const nodesByModuleId = /* @__PURE__ */ new Map([[args.bundleRoot.moduleId, root.node]]);
27604
- const queue = [root.node];
27607
+ const queue2 = [root.node];
27605
27608
  let exactFactoryMatches = 0;
27606
27609
  let uniqueChildFactoryMatches = 0;
27607
27610
  let uniqueChildAtomMatches = 0;
27608
27611
  let weakRootMatch = false;
27609
- for (let cursor = 0; cursor < queue.length; cursor++) {
27610
- const nodeIndex = queue[cursor];
27612
+ for (let cursor = 0; cursor < queue2.length; cursor++) {
27613
+ const nodeIndex = queue2[cursor];
27611
27614
  const moduleId = moduleIdsByNode.get(nodeIndex);
27612
27615
  if (moduleId === void 0) return null;
27613
27616
  const bundleModule = args.bundleById.get(moduleId);
@@ -27646,7 +27649,7 @@ function embedTemplateRoot(args) {
27646
27649
  if (existingModuleId === void 0) {
27647
27650
  moduleIdsByNode.set(edge.node, dependencyId);
27648
27651
  nodesByModuleId.set(dependencyId, edge.node);
27649
- queue.push(edge.node);
27652
+ queue2.push(edge.node);
27650
27653
  }
27651
27654
  }
27652
27655
  }
@@ -28175,39 +28178,82 @@ function detectFramework2(deps) {
28175
28178
  return "unknown";
28176
28179
  }
28177
28180
  function detectProject(dir) {
28178
- const pkgPath = (0, import_path2.join)(dir, "package.json");
28179
- if (!(0, import_fs2.existsSync)(pkgPath)) return null;
28180
- let pkg;
28181
- try {
28182
- pkg = JSON.parse((0, import_fs2.readFileSync)(pkgPath, "utf8"));
28183
- } catch {
28184
- return null;
28185
- }
28181
+ const pkgPath = (0, import_node_path16.join)(dir, "package.json");
28182
+ if (!(0, import_node_fs15.existsSync)(pkgPath)) return null;
28183
+ const pkg = readProjectManifest(dir);
28184
+ if (!pkg) return null;
28186
28185
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
28186
+ const devCommand = metadataValue(
28187
+ metadataValue(readProjectJson(pkgPath), "scripts"),
28188
+ "dev"
28189
+ );
28187
28190
  const framework = detectFramework2(deps);
28188
28191
  if (framework === "unknown") return null;
28189
28192
  return {
28190
28193
  dir,
28191
- name: pkg.name || (0, import_path2.basename)(dir),
28194
+ name: pkg.name || (0, import_node_path16.basename)(dir),
28192
28195
  framework,
28193
28196
  // a config file is a config file whatever module system it declares. real
28194
28197
  // apps write .cjs as often as .js, and missing one reads as "this project
28195
28198
  // has no bundler config" and sends the user to create a second one.
28196
28199
  hasViteConfig: CONFIG_EXTENSIONS.some(
28197
- (ext) => (0, import_fs2.existsSync)((0, import_path2.join)(dir, `vite.config.${ext}`))
28200
+ (ext) => (0, import_node_fs15.existsSync)((0, import_node_path16.join)(dir, `vite.config.${ext}`))
28198
28201
  ),
28199
28202
  hasMetroConfig: CONFIG_EXTENSIONS.some(
28200
- (ext) => (0, import_fs2.existsSync)((0, import_path2.join)(dir, `metro.config.${ext}`))
28203
+ (ext) => (0, import_node_fs15.existsSync)((0, import_node_path16.join)(dir, `metro.config.${ext}`))
28201
28204
  ),
28202
- devCommand: pkg.scripts?.dev || null
28205
+ devCommand: typeof devCommand === "string" ? devCommand : null
28206
+ };
28207
+ }
28208
+ function readProjectMetadata(path22) {
28209
+ try {
28210
+ const info = (0, import_node_fs15.lstatSync)(path22);
28211
+ if (!info.isFile() || info.size > 4 * 1024 * 1024) return null;
28212
+ return (0, import_node_fs15.readFileSync)(path22, "utf8");
28213
+ } catch {
28214
+ return null;
28215
+ }
28216
+ }
28217
+ function metadataValue(value, key) {
28218
+ if (!value || typeof value !== "object") return void 0;
28219
+ return Object.getOwnPropertyDescriptor(value, key)?.value;
28220
+ }
28221
+ function readProjectJson(path22) {
28222
+ const text = readProjectMetadata(path22);
28223
+ if (text === null) return null;
28224
+ try {
28225
+ const value = JSON.parse(text);
28226
+ return value;
28227
+ } catch {
28228
+ return null;
28229
+ }
28230
+ }
28231
+ function readProjectManifest(dir) {
28232
+ const parsed = readProjectJson((0, import_node_path16.join)(dir, "package.json"));
28233
+ if (!parsed || typeof parsed !== "object") return null;
28234
+ const record = (value) => {
28235
+ if (!value || typeof value !== "object") return {};
28236
+ return Object.fromEntries(
28237
+ Object.entries(value).filter(
28238
+ (entry) => typeof entry[1] === "string" && /^(?:@[a-z0-9._-]+\/)?[a-z0-9._-]+$/i.test(entry[0]) && entry[0] !== "." && entry[0] !== ".."
28239
+ )
28240
+ );
28241
+ };
28242
+ const name2 = metadataValue(parsed, "name");
28243
+ return {
28244
+ ...typeof name2 === "string" ? { name: name2 } : {},
28245
+ dependencies: record(metadataValue(parsed, "dependencies")),
28246
+ devDependencies: record(metadataValue(parsed, "devDependencies"))
28203
28247
  };
28204
28248
  }
28205
- var import_fs2, import_path2, CONFIG_EXTENSIONS;
28249
+ var import_node_fs15, import_node_path16, import_json5, import_yaml, CONFIG_EXTENSIONS;
28206
28250
  var init_detect = __esm({
28207
28251
  "cli/commands/detect.ts"() {
28208
28252
  "use strict";
28209
- import_fs2 = require("fs");
28210
- import_path2 = require("path");
28253
+ import_node_fs15 = require("node:fs");
28254
+ import_node_path16 = require("node:path");
28255
+ import_json5 = __toESM(require("json5"), 1);
28256
+ import_yaml = require("yaml");
28211
28257
  CONFIG_EXTENSIONS = ["ts", "js", "cjs", "mjs", "mts", "cts"];
28212
28258
  }
28213
28259
  });
@@ -28242,21 +28288,21 @@ function resolveCloudOrigin(value) {
28242
28288
  return normalizeCloudOrigin(source);
28243
28289
  }
28244
28290
  function readImmutableBundleSource(bundlePath) {
28245
- const filepath = (0, import_node_path16.resolve)(bundlePath);
28246
- if ((0, import_node_path16.extname)(filepath) !== ".js") {
28291
+ const filepath = (0, import_node_path17.resolve)(bundlePath);
28292
+ if ((0, import_node_path17.extname)(filepath) !== ".js") {
28247
28293
  throw new Error(`${REMOTE_COMMAND} requires one local Metro .js bundle`);
28248
28294
  }
28249
- const descriptor = (0, import_node_fs15.openSync)(filepath, "r");
28295
+ const descriptor = (0, import_node_fs16.openSync)(filepath, "r");
28250
28296
  try {
28251
- const before = (0, import_node_fs15.fstatSync)(descriptor, { bigint: true });
28297
+ const before = (0, import_node_fs16.fstatSync)(descriptor, { bigint: true });
28252
28298
  if (!before.isFile()) {
28253
28299
  throw new Error(`${REMOTE_COMMAND} bundle must be a regular local file`);
28254
28300
  }
28255
28301
  if (before.size <= 0n) {
28256
28302
  throw new Error(`${REMOTE_COMMAND} bundle is empty`);
28257
28303
  }
28258
- const bytes = (0, import_node_fs15.readFileSync)(descriptor);
28259
- const after = (0, import_node_fs15.fstatSync)(descriptor, { bigint: true });
28304
+ const bytes = (0, import_node_fs16.readFileSync)(descriptor);
28305
+ const after = (0, import_node_fs16.fstatSync)(descriptor, { bigint: true });
28260
28306
  if (before.dev !== after.dev || before.ino !== after.ino || before.size !== after.size || before.mtimeNs !== after.mtimeNs || bytes.length !== Number(before.size)) {
28261
28307
  throw new Error(`${REMOTE_COMMAND} bundle changed while it was being read`);
28262
28308
  }
@@ -28271,7 +28317,7 @@ function readImmutableBundleSource(bundlePath) {
28271
28317
  }
28272
28318
  return source;
28273
28319
  } finally {
28274
- (0, import_node_fs15.closeSync)(descriptor);
28320
+ (0, import_node_fs16.closeSync)(descriptor);
28275
28321
  }
28276
28322
  }
28277
28323
  async function fetchBundleSource(bundleUrl) {
@@ -28318,15 +28364,15 @@ async function loadBundleSource(bundleInput) {
28318
28364
  return readImmutableBundleSource(bundleInput);
28319
28365
  }
28320
28366
  function listMetroAssetDest(assetsPath) {
28321
- const directory = (0, import_node_path16.resolve)(assetsPath);
28322
- if (!(0, import_node_fs15.existsSync)(directory)) return { directory, files: [], truncated: false };
28323
- const skipNested = (0, import_node_fs15.existsSync)((0, import_node_path16.join)(directory, "package.json"));
28367
+ const directory = (0, import_node_path17.resolve)(assetsPath);
28368
+ if (!(0, import_node_fs16.existsSync)(directory)) return { directory, files: [], truncated: false };
28369
+ const skipNested = (0, import_node_fs16.existsSync)((0, import_node_path17.join)(directory, "package.json"));
28324
28370
  const files = [];
28325
28371
  let truncated = false;
28326
28372
  const walk = (dir, prefix) => {
28327
28373
  let entries;
28328
28374
  try {
28329
- entries = (0, import_node_fs15.readdirSync)(dir, { withFileTypes: true });
28375
+ entries = (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true });
28330
28376
  } catch {
28331
28377
  return;
28332
28378
  }
@@ -28338,7 +28384,7 @@ function listMetroAssetDest(assetsPath) {
28338
28384
  if (entry.isDirectory()) {
28339
28385
  if (entry.name === ".git") continue;
28340
28386
  if (skipNested && PROJECT_ONLY_DIRECTORIES.has(entry.name)) continue;
28341
- walk((0, import_node_path16.join)(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name);
28387
+ walk((0, import_node_path17.join)(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name);
28342
28388
  } else if (entry.isFile()) {
28343
28389
  files.push(prefix ? `${prefix}/${entry.name}` : entry.name);
28344
28390
  }
@@ -28373,7 +28419,7 @@ function distinctByContent(directory, options) {
28373
28419
  for (const relative2 of options) {
28374
28420
  let bytes;
28375
28421
  try {
28376
- bytes = (0, import_node_fs15.readFileSync)((0, import_node_path16.join)(directory, relative2));
28422
+ bytes = (0, import_node_fs16.readFileSync)((0, import_node_path17.join)(directory, relative2));
28377
28423
  } catch {
28378
28424
  continue;
28379
28425
  }
@@ -28405,7 +28451,7 @@ function placeMetroDescriptor(listing, descriptor) {
28405
28451
  let bytes;
28406
28452
  try {
28407
28453
  bytes = combination.map(
28408
- (relative2) => (0, import_node_fs15.readFileSync)((0, import_node_path16.join)(listing.directory, relative2))
28454
+ (relative2) => (0, import_node_fs16.readFileSync)((0, import_node_path17.join)(listing.directory, relative2))
28409
28455
  );
28410
28456
  } catch {
28411
28457
  continue;
@@ -28431,26 +28477,26 @@ function placeMetroDescriptor(listing, descriptor) {
28431
28477
  }
28432
28478
  function unverifiedFileKey(dest) {
28433
28479
  return dest.placements.filter((placement) => !placement.verified).flatMap(
28434
- (placement) => [...placement.files.values()].map((relative2) => (0, import_node_path16.join)(dest.directory, relative2))
28480
+ (placement) => [...placement.files.values()].map((relative2) => (0, import_node_path17.join)(dest.directory, relative2))
28435
28481
  ).sort().join("\n");
28436
28482
  }
28437
28483
  function searchMetroAssetDest(bundlePath, descriptors) {
28438
- const bundleDirectory = (0, import_node_path16.dirname)((0, import_node_path16.resolve)(bundlePath));
28484
+ const bundleDirectory = (0, import_node_path17.dirname)((0, import_node_path17.resolve)(bundlePath));
28439
28485
  const candidates = [
28440
- (0, import_node_path16.join)(bundleDirectory, "assets"),
28486
+ (0, import_node_path17.join)(bundleDirectory, "assets"),
28441
28487
  bundleDirectory,
28442
- (0, import_node_path16.resolve)(bundleDirectory, "..", "assets")
28488
+ (0, import_node_path17.resolve)(bundleDirectory, "..", "assets")
28443
28489
  ];
28444
28490
  const cwd = process.cwd();
28445
28491
  let projectDirectory = null;
28446
28492
  for (const start of [bundleDirectory, cwd]) {
28447
- let directory = (0, import_node_path16.resolve)(start);
28493
+ let directory = (0, import_node_path17.resolve)(start);
28448
28494
  while (true) {
28449
28495
  if (detectProject(directory)?.hasMetroConfig) {
28450
28496
  projectDirectory = directory;
28451
28497
  break;
28452
28498
  }
28453
- const parent = (0, import_node_path16.dirname)(directory);
28499
+ const parent = (0, import_node_path17.dirname)(directory);
28454
28500
  if (parent === directory) break;
28455
28501
  directory = parent;
28456
28502
  }
@@ -28458,11 +28504,11 @@ function searchMetroAssetDest(bundlePath, descriptors) {
28458
28504
  }
28459
28505
  if (projectDirectory) {
28460
28506
  candidates.push(
28461
- (0, import_node_path16.join)(projectDirectory, "assets"),
28462
- (0, import_node_path16.join)(projectDirectory, "dist"),
28463
- (0, import_node_path16.join)(projectDirectory, "dist", "assets"),
28464
- (0, import_node_path16.join)(projectDirectory, "build"),
28465
- (0, import_node_path16.join)(projectDirectory, "build", "assets")
28507
+ (0, import_node_path17.join)(projectDirectory, "assets"),
28508
+ (0, import_node_path17.join)(projectDirectory, "dist"),
28509
+ (0, import_node_path17.join)(projectDirectory, "dist", "assets"),
28510
+ (0, import_node_path17.join)(projectDirectory, "build"),
28511
+ (0, import_node_path17.join)(projectDirectory, "build", "assets")
28466
28512
  );
28467
28513
  }
28468
28514
  const searched = [];
@@ -28470,7 +28516,7 @@ function searchMetroAssetDest(bundlePath, descriptors) {
28470
28516
  const stale = [];
28471
28517
  let truncated = false;
28472
28518
  for (const candidate of candidates) {
28473
- const directory = (0, import_node_path16.resolve)(candidate);
28519
+ const directory = (0, import_node_path17.resolve)(candidate);
28474
28520
  if (searched.includes(directory)) continue;
28475
28521
  searched.push(directory);
28476
28522
  const listing = listMetroAssetDest(directory);
@@ -28576,7 +28622,7 @@ async function embedBundleAssets(bundlePath, command, assetPolicy) {
28576
28622
  );
28577
28623
  }
28578
28624
  const relative2 = placement?.files.get(variant.scale);
28579
- if (relative2 && dest) return (0, import_node_fs15.readFileSync)((0, import_node_path16.join)(dest.directory, relative2));
28625
+ if (relative2 && dest) return (0, import_node_fs16.readFileSync)((0, import_node_path17.join)(dest.directory, relative2));
28580
28626
  if (placement && placement.files.size > 0) return null;
28581
28627
  if (placement && placement.ambiguous.length > 0 && dest) {
28582
28628
  throw new Error(
@@ -28605,7 +28651,7 @@ async function embedBundleAssets(bundlePath, command, assetPolicy) {
28605
28651
  );
28606
28652
  const classic = metroIosAssetDestRelatives(variant.descriptor.httpServerLocation, filename)[0] ?? filename;
28607
28653
  throw new Error(
28608
- `${command} could not read ${(0, import_node_path16.join)(dest?.directory ?? ".", classic)} for ${variant.descriptor.name}.${variant.descriptor.type} at scale ${variant.scale}, and has no stand-in for a .${variant.descriptor.type} asset. Rebuild with \`react-native bundle --assets-dest\`.`
28654
+ `${command} could not read ${(0, import_node_path17.join)(dest?.directory ?? ".", classic)} for ${variant.descriptor.name}.${variant.descriptor.type} at scale ${variant.scale}, and has no stand-in for a .${variant.descriptor.type} asset. Rebuild with \`react-native bundle --assets-dest\`.`
28609
28655
  );
28610
28656
  });
28611
28657
  return {
@@ -28791,13 +28837,13 @@ function createCloudBridgeForParsed(parsed) {
28791
28837
  if (!session) return null;
28792
28838
  return session.service === "box" ? new CloudBoxBridge(session) : new CloudBridge(session);
28793
28839
  }
28794
- var import_node_crypto6, import_node_fs15, import_node_path16, DEFAULT_RNX_CLOUD_ORIGIN, MAX_RNX_CLOUD_BUNDLE_BYTES, REMOTE_COMMAND, MAX_ASSET_DEST_FILES, ACCOUNT_CHOICE_REFUSALS, PROJECT_ONLY_DIRECTORIES, MAX_PLACEMENT_COMBINATIONS, CloudBridge, CloudBoxBridge;
28840
+ var import_node_crypto6, import_node_fs16, import_node_path17, DEFAULT_RNX_CLOUD_ORIGIN, MAX_RNX_CLOUD_BUNDLE_BYTES, REMOTE_COMMAND, MAX_ASSET_DEST_FILES, ACCOUNT_CHOICE_REFUSALS, PROJECT_ONLY_DIRECTORIES, MAX_PLACEMENT_COMBINATIONS, CloudBridge, CloudBoxBridge;
28795
28841
  var init_cloud_client = __esm({
28796
28842
  "cli/cloud-client.ts"() {
28797
28843
  "use strict";
28798
28844
  import_node_crypto6 = require("node:crypto");
28799
- import_node_fs15 = require("node:fs");
28800
- import_node_path16 = require("node:path");
28845
+ import_node_fs16 = require("node:fs");
28846
+ import_node_path17 = require("node:path");
28801
28847
  init_metroAssetArtifact();
28802
28848
  init_metroCloudArtifact();
28803
28849
  init_metro_fingerprint_registry_client();
@@ -29068,14 +29114,14 @@ function unrefTimer(timer) {
29068
29114
  timer.unref();
29069
29115
  }
29070
29116
  }
29071
- var import_child_process3, import_fs3, import_http4, import_path3, import_ws, SOOTSIM_CROSS_ORIGIN_EMBEDDER_POLICY, WRITE_COMMAND_TYPES, FORCE_CLOSE_GRACE_MS, FORCE_CLOSE_TERMINATE_MS, DAEMON_HEARTBEAT_INTERVAL_MS, DEFAULT_RUNTIME_UPDATE_INTERVAL_MS, RUNTIME_UPDATE_INTERVAL_ENV, HTTP_MIME_TYPES, CAMERA_FIXTURE_ROUTE, CAMERA_FIXTURE_NAME_RE, SootSimBridgeHost;
29117
+ var import_child_process3, import_fs2, import_http4, import_path2, import_ws, SOOTSIM_CROSS_ORIGIN_EMBEDDER_POLICY, WRITE_COMMAND_TYPES, FORCE_CLOSE_GRACE_MS, FORCE_CLOSE_TERMINATE_MS, DAEMON_HEARTBEAT_INTERVAL_MS, DEFAULT_RUNTIME_UPDATE_INTERVAL_MS, RUNTIME_UPDATE_INTERVAL_ENV, HTTP_MIME_TYPES, CAMERA_FIXTURE_ROUTE, CAMERA_FIXTURE_NAME_RE, SootSimBridgeHost;
29072
29118
  var init_bridge_host = __esm({
29073
29119
  "src/host/bridge-host.ts"() {
29074
29120
  "use strict";
29075
29121
  import_child_process3 = require("child_process");
29076
- import_fs3 = __toESM(require("fs"), 1);
29122
+ import_fs2 = __toESM(require("fs"), 1);
29077
29123
  import_http4 = require("http");
29078
- import_path3 = __toESM(require("path"), 1);
29124
+ import_path2 = __toESM(require("path"), 1);
29079
29125
  import_ws = require("ws");
29080
29126
  init_dev_server_scanner();
29081
29127
  init_backend_origin();
@@ -29233,7 +29279,7 @@ var init_bridge_host = __esm({
29233
29279
  async startAsync(options) {
29234
29280
  if (this.httpServer || this.wss) return this.effectivePort;
29235
29281
  this.refreshActiveRuntime();
29236
- this.bootstrapping = !this.activeRuntimeDirPath || !import_fs3.default.existsSync(import_path3.default.join(this.activeRuntimeDirPath, "index.html"));
29282
+ this.bootstrapping = !this.activeRuntimeDirPath || !import_fs2.default.existsSync(import_path2.default.join(this.activeRuntimeDirPath, "index.html"));
29237
29283
  for (let attempt = 0; attempt < this.portFallbackCount; attempt++) {
29238
29284
  const candidate = this.preferredPort + attempt;
29239
29285
  try {
@@ -29905,10 +29951,10 @@ var init_bridge_host = __esm({
29905
29951
  return;
29906
29952
  }
29907
29953
  const root = cameraFixturesDir();
29908
- const filePath = import_path3.default.join(root, name2);
29954
+ const filePath = import_path2.default.join(root, name2);
29909
29955
  let stats;
29910
29956
  try {
29911
- stats = import_fs3.default.lstatSync(filePath);
29957
+ stats = import_fs2.default.lstatSync(filePath);
29912
29958
  } catch {
29913
29959
  res.writeHead(404, { ...cors, "Content-Type": "text/plain; charset=utf-8" });
29914
29960
  res.end("not found");
@@ -29919,7 +29965,7 @@ var init_bridge_host = __esm({
29919
29965
  res.end("forbidden");
29920
29966
  return;
29921
29967
  }
29922
- const contentType = HTTP_MIME_TYPES[import_path3.default.extname(filePath).toLowerCase()] || "application/octet-stream";
29968
+ const contentType = HTTP_MIME_TYPES[import_path2.default.extname(filePath).toLowerCase()] || "application/octet-stream";
29923
29969
  sendFileWithRanges(req, res, filePath, stats.size, {
29924
29970
  ...cors,
29925
29971
  "Content-Type": contentType
@@ -30296,34 +30342,34 @@ var init_bridge_host = __esm({
30296
30342
  return;
30297
30343
  }
30298
30344
  }
30299
- const resolved = import_path3.default.resolve(baseDir, "." + rel);
30300
- const baseWithSep = baseDir.endsWith(import_path3.default.sep) ? baseDir : baseDir + import_path3.default.sep;
30345
+ const resolved = import_path2.default.resolve(baseDir, "." + rel);
30346
+ const baseWithSep = baseDir.endsWith(import_path2.default.sep) ? baseDir : baseDir + import_path2.default.sep;
30301
30347
  if (!resolved.startsWith(baseWithSep) && resolved !== baseDir) {
30302
30348
  res.writeHead(403);
30303
30349
  res.end("forbidden");
30304
30350
  return;
30305
30351
  }
30306
- import_fs3.default.realpath(resolved, (realErr, realResolved) => {
30352
+ import_fs2.default.realpath(resolved, (realErr, realResolved) => {
30307
30353
  const servePath = realErr ? resolved : realResolved;
30308
- const servePathWithSep = servePath.endsWith(import_path3.default.sep) ? servePath : servePath + import_path3.default.sep;
30354
+ const servePathWithSep = servePath.endsWith(import_path2.default.sep) ? servePath : servePath + import_path2.default.sep;
30309
30355
  if (!realErr) {
30310
30356
  const realBaseWithSep = (() => {
30311
30357
  try {
30312
- const rb = import_fs3.default.realpathSync(baseDir);
30313
- return rb.endsWith(import_path3.default.sep) ? rb : rb + import_path3.default.sep;
30358
+ const rb = import_fs2.default.realpathSync(baseDir);
30359
+ return rb.endsWith(import_path2.default.sep) ? rb : rb + import_path2.default.sep;
30314
30360
  } catch {
30315
30361
  return baseWithSep;
30316
30362
  }
30317
30363
  })();
30318
- if (!servePathWithSep.startsWith(realBaseWithSep) && servePath + import_path3.default.sep !== realBaseWithSep) {
30364
+ if (!servePathWithSep.startsWith(realBaseWithSep) && servePath + import_path2.default.sep !== realBaseWithSep) {
30319
30365
  res.writeHead(403);
30320
30366
  res.end("forbidden");
30321
30367
  return;
30322
30368
  }
30323
30369
  }
30324
- import_fs3.default.stat(servePath, (err, stats) => {
30370
+ import_fs2.default.stat(servePath, (err, stats) => {
30325
30371
  if (err || !stats?.isFile()) {
30326
- const ext2 = import_path3.default.extname(rel).toLowerCase();
30372
+ const ext2 = import_path2.default.extname(rel).toLowerCase();
30327
30373
  if (ext2 && ext2 !== ".html") {
30328
30374
  res.writeHead(404);
30329
30375
  res.end("not found");
@@ -30334,8 +30380,8 @@ var init_bridge_host = __esm({
30334
30380
  res.end("not found");
30335
30381
  return;
30336
30382
  }
30337
- const indexPath = import_path3.default.join(baseDir, "index.html");
30338
- import_fs3.default.readFile(indexPath, (err2, data) => {
30383
+ const indexPath = import_path2.default.join(baseDir, "index.html");
30384
+ import_fs2.default.readFile(indexPath, (err2, data) => {
30339
30385
  if (err2) {
30340
30386
  res.writeHead(404);
30341
30387
  res.end("not found");
@@ -30355,7 +30401,7 @@ var init_bridge_host = __esm({
30355
30401
  });
30356
30402
  return;
30357
30403
  }
30358
- const ext = import_path3.default.extname(servePath).toLowerCase();
30404
+ const ext = import_path2.default.extname(servePath).toLowerCase();
30359
30405
  const contentType = HTTP_MIME_TYPES[ext] || "application/octet-stream";
30360
30406
  res.writeHead(200, {
30361
30407
  "Content-Type": contentType,
@@ -30366,7 +30412,7 @@ var init_bridge_host = __esm({
30366
30412
  return;
30367
30413
  }
30368
30414
  if (ext === ".html") {
30369
- import_fs3.default.readFile(servePath, (readErr, data) => {
30415
+ import_fs2.default.readFile(servePath, (readErr, data) => {
30370
30416
  if (readErr) {
30371
30417
  try {
30372
30418
  res.end();
@@ -30380,7 +30426,7 @@ var init_bridge_host = __esm({
30380
30426
  });
30381
30427
  return;
30382
30428
  }
30383
- const stream = import_fs3.default.createReadStream(servePath);
30429
+ const stream = import_fs2.default.createReadStream(servePath);
30384
30430
  stream.pipe(res);
30385
30431
  stream.on("error", () => {
30386
30432
  try {
@@ -31067,7 +31113,7 @@ function buildComm() {
31067
31113
  if (process.platform === "linux") {
31068
31114
  return (pid) => {
31069
31115
  try {
31070
- return (0, import_fs4.readFileSync)(`/proc/${pid}/comm`, "utf8").trim() || null;
31116
+ return (0, import_fs3.readFileSync)(`/proc/${pid}/comm`, "utf8").trim() || null;
31071
31117
  } catch {
31072
31118
  return null;
31073
31119
  }
@@ -31125,7 +31171,7 @@ function readProcessTable() {
31125
31171
  function buildLinux() {
31126
31172
  return (pid) => {
31127
31173
  try {
31128
- const raw = (0, import_fs4.readFileSync)(`/proc/${pid}/stat`, "utf8");
31174
+ const raw = (0, import_fs3.readFileSync)(`/proc/${pid}/stat`, "utf8");
31129
31175
  const end = raw.lastIndexOf(")");
31130
31176
  if (end < 0) return null;
31131
31177
  const rest = raw.slice(end + 1).trim().split(/\s+/);
@@ -31186,12 +31232,12 @@ function tryBuildDarwinCommFfi() {
31186
31232
  return null;
31187
31233
  }
31188
31234
  }
31189
- var import_child_process4, import_fs4, import_module, cached3, cachedComm, PROCESS_TABLE_TTL_MS, processTable, PROC_PIDTBSDINFO, PROC_BSDINFO_SIZE, PBI_PPID_OFFSET, PBI_COMM_OFFSET, PBI_COMM_LEN;
31235
+ var import_child_process4, import_fs3, import_module, cached3, cachedComm, PROCESS_TABLE_TTL_MS, processTable, PROC_PIDTBSDINFO, PROC_BSDINFO_SIZE, PBI_PPID_OFFSET, PBI_COMM_OFFSET, PBI_COMM_LEN;
31190
31236
  var init_parent_pid = __esm({
31191
31237
  "cli/parent-pid.ts"() {
31192
31238
  "use strict";
31193
31239
  import_child_process4 = require("child_process");
31194
- import_fs4 = require("fs");
31240
+ import_fs3 = require("fs");
31195
31241
  import_module = require("module");
31196
31242
  cached3 = null;
31197
31243
  cachedComm = null;
@@ -31207,31 +31253,31 @@ var init_parent_pid = __esm({
31207
31253
 
31208
31254
  // cli/secure-file.ts
31209
31255
  function writeSecureJsonAtomic(filepath, value) {
31210
- (0, import_node_fs16.mkdirSync)((0, import_node_path17.dirname)(filepath), { recursive: true });
31256
+ (0, import_node_fs17.mkdirSync)((0, import_node_path18.dirname)(filepath), { recursive: true });
31211
31257
  const temporary = `${filepath}.tmp-${process.pid}-${(0, import_node_crypto7.randomUUID)()}`;
31212
31258
  let descriptor = null;
31213
31259
  try {
31214
- descriptor = (0, import_node_fs16.openSync)(temporary, "wx", 384);
31215
- (0, import_node_fs16.fchmodSync)(descriptor, 384);
31216
- (0, import_node_fs16.writeFileSync)(descriptor, `${JSON.stringify(value, null, 2)}
31260
+ descriptor = (0, import_node_fs17.openSync)(temporary, "wx", 384);
31261
+ (0, import_node_fs17.fchmodSync)(descriptor, 384);
31262
+ (0, import_node_fs17.writeFileSync)(descriptor, `${JSON.stringify(value, null, 2)}
31217
31263
  `);
31218
- (0, import_node_fs16.fsyncSync)(descriptor);
31219
- (0, import_node_fs16.closeSync)(descriptor);
31264
+ (0, import_node_fs17.fsyncSync)(descriptor);
31265
+ (0, import_node_fs17.closeSync)(descriptor);
31220
31266
  descriptor = null;
31221
- (0, import_node_fs16.renameSync)(temporary, filepath);
31267
+ (0, import_node_fs17.renameSync)(temporary, filepath);
31222
31268
  } catch (error) {
31223
- if (descriptor !== null) (0, import_node_fs16.closeSync)(descriptor);
31224
- (0, import_node_fs16.rmSync)(temporary, { force: true });
31269
+ if (descriptor !== null) (0, import_node_fs17.closeSync)(descriptor);
31270
+ (0, import_node_fs17.rmSync)(temporary, { force: true });
31225
31271
  throw error;
31226
31272
  }
31227
31273
  }
31228
- var import_node_crypto7, import_node_fs16, import_node_path17;
31274
+ var import_node_crypto7, import_node_fs17, import_node_path18;
31229
31275
  var init_secure_file = __esm({
31230
31276
  "cli/secure-file.ts"() {
31231
31277
  "use strict";
31232
31278
  import_node_crypto7 = require("node:crypto");
31233
- import_node_fs16 = require("node:fs");
31234
- import_node_path17 = require("node:path");
31279
+ import_node_fs17 = require("node:fs");
31280
+ import_node_path18 = require("node:path");
31235
31281
  }
31236
31282
  });
31237
31283
 
@@ -31276,22 +31322,22 @@ function getStableOwnerPid() {
31276
31322
  }
31277
31323
  function getCurrentSimPath() {
31278
31324
  if (process.env[CURRENT_SIM_PATH_ENV]) {
31279
- return (0, import_path4.resolve)(process.env[CURRENT_SIM_PATH_ENV]);
31325
+ return (0, import_path3.resolve)(process.env[CURRENT_SIM_PATH_ENV]);
31280
31326
  }
31281
31327
  const key = getCliIdentityKey();
31282
- return (0, import_path4.join)((0, import_os.tmpdir)(), `peach-current-sim-${key}.json`);
31328
+ return (0, import_path3.join)((0, import_os.tmpdir)(), `peach-current-sim-${key}.json`);
31283
31329
  }
31284
31330
  function legacyCloudCredentialDirectory(filepath) {
31285
- return (0, import_path4.join)((0, import_path4.dirname)(filepath), `${(0, import_path4.basename)(filepath)}.credentials`);
31331
+ return (0, import_path3.join)((0, import_path3.dirname)(filepath), `${(0, import_path3.basename)(filepath)}.credentials`);
31286
31332
  }
31287
31333
  function readCurrentTarget() {
31288
31334
  const filepath = getCurrentSimPath();
31289
- (0, import_fs5.rmSync)(legacyCloudCredentialDirectory(filepath), { recursive: true, force: true });
31290
- if (!(0, import_fs5.existsSync)(filepath)) return null;
31335
+ (0, import_fs4.rmSync)(legacyCloudCredentialDirectory(filepath), { recursive: true, force: true });
31336
+ if (!(0, import_fs4.existsSync)(filepath)) return null;
31291
31337
  try {
31292
- const parsed = JSON.parse((0, import_fs5.readFileSync)(filepath, "utf8"));
31338
+ const parsed = JSON.parse((0, import_fs4.readFileSync)(filepath, "utf8"));
31293
31339
  if (parsed === null || typeof parsed !== "object") {
31294
- (0, import_fs5.rmSync)(filepath, { force: true });
31340
+ (0, import_fs4.rmSync)(filepath, { force: true });
31295
31341
  return null;
31296
31342
  }
31297
31343
  const version = Reflect.get(parsed, "version");
@@ -31299,7 +31345,7 @@ function readCurrentTarget() {
31299
31345
  const simId = Reflect.get(parsed, "simId");
31300
31346
  const updatedAt = Reflect.get(parsed, "updatedAt");
31301
31347
  if (version !== 1 && version !== CURRENT_SIM_VERSION || version === CURRENT_SIM_VERSION && plane !== "local" || typeof simId !== "string" || !simId.trim() || typeof updatedAt !== "string") {
31302
- (0, import_fs5.rmSync)(filepath, { force: true });
31348
+ (0, import_fs4.rmSync)(filepath, { force: true });
31303
31349
  return null;
31304
31350
  }
31305
31351
  const target = {
@@ -31311,7 +31357,7 @@ function readCurrentTarget() {
31311
31357
  if (version === 1) writeSecureJsonAtomic(filepath, target);
31312
31358
  return target;
31313
31359
  } catch {
31314
- (0, import_fs5.rmSync)(filepath, { force: true });
31360
+ (0, import_fs4.rmSync)(filepath, { force: true });
31315
31361
  return null;
31316
31362
  }
31317
31363
  }
@@ -31329,15 +31375,15 @@ function saveCurrentSimId(simId) {
31329
31375
  });
31330
31376
  }
31331
31377
  function clearCurrentSimId() {
31332
- (0, import_fs5.rmSync)(getCurrentSimPath(), { force: true });
31378
+ (0, import_fs4.rmSync)(getCurrentSimPath(), { force: true });
31333
31379
  }
31334
- var import_fs5, import_os, import_path4, CURRENT_SIM_VERSION, CURRENT_SIM_PATH_ENV, IDENTITY_ENV_VARS, IMMORTAL_HOST_COMM_RE, readCurrentSim;
31380
+ var import_fs4, import_os, import_path3, CURRENT_SIM_VERSION, CURRENT_SIM_PATH_ENV, IDENTITY_ENV_VARS, IMMORTAL_HOST_COMM_RE, readCurrentSim;
31335
31381
  var init_current_sim = __esm({
31336
31382
  "cli/current-sim.ts"() {
31337
31383
  "use strict";
31338
- import_fs5 = require("fs");
31384
+ import_fs4 = require("fs");
31339
31385
  import_os = require("os");
31340
- import_path4 = require("path");
31386
+ import_path3 = require("path");
31341
31387
  init_parent_pid();
31342
31388
  init_secure_file();
31343
31389
  CURRENT_SIM_VERSION = 2;
@@ -31406,17 +31452,17 @@ function liveDevBridgeLockfiles() {
31406
31452
  return readDevBridgeLockfiles().filter((lockfile) => isDevBridgeLockfileFresh(lockfile));
31407
31453
  }
31408
31454
  function checkoutRoot(cwd) {
31409
- let current = import_node_path18.default.resolve(cwd);
31455
+ let current = import_node_path19.default.resolve(cwd);
31410
31456
  while (true) {
31411
- if (import_node_fs17.default.existsSync(import_node_path18.default.join(current, ".git"))) return current;
31412
- const parent = import_node_path18.default.dirname(current);
31457
+ if (import_node_fs18.default.existsSync(import_node_path19.default.join(current, ".git"))) return current;
31458
+ const parent = import_node_path19.default.dirname(current);
31413
31459
  if (parent === current) return null;
31414
31460
  current = parent;
31415
31461
  }
31416
31462
  }
31417
31463
  function pathContains(parent, child) {
31418
- const relative2 = import_node_path18.default.relative(parent, child);
31419
- return relative2 === "" || relative2 !== ".." && !relative2.startsWith(`..${import_node_path18.default.sep}`) && !import_node_path18.default.isAbsolute(relative2);
31464
+ const relative2 = import_node_path19.default.relative(parent, child);
31465
+ return relative2 === "" || relative2 !== ".." && !relative2.startsWith(`..${import_node_path19.default.sep}`) && !import_node_path19.default.isAbsolute(relative2);
31420
31466
  }
31421
31467
  function resolveDefaultDevBridgeLockfile() {
31422
31468
  const lockfiles = liveDevBridgeLockfiles();
@@ -31914,12 +31960,12 @@ async function callInBridge(bridge, path22, ...args) {
31914
31960
  async function callInBridgeWrite(bridge, path22, ...args) {
31915
31961
  return bridge.send({ type: "call", path: path22, args, acquireLock: true });
31916
31962
  }
31917
- var import_node_fs17, import_node_path18, import_ws2, PEACH_PLACEMENT_ENV, resolvedWorld, BridgeSimLockedError, BRIDGE_VALUE_FLAGS_TABLE, BRIDGE_VALUE_FLAGS;
31963
+ var import_node_fs18, import_node_path19, import_ws2, PEACH_PLACEMENT_ENV, resolvedWorld, BridgeSimLockedError, BRIDGE_VALUE_FLAGS_TABLE, BRIDGE_VALUE_FLAGS;
31918
31964
  var init_ws_bridge = __esm({
31919
31965
  "cli/ws-bridge.ts"() {
31920
31966
  "use strict";
31921
- import_node_fs17 = __toESM(require("node:fs"), 1);
31922
- import_node_path18 = __toESM(require("node:path"), 1);
31967
+ import_node_fs18 = __toESM(require("node:fs"), 1);
31968
+ import_node_path19 = __toESM(require("node:path"), 1);
31923
31969
  import_ws2 = require("ws");
31924
31970
  init_bridge_constants();
31925
31971
  init_cli_constants();
@@ -32231,9 +32277,9 @@ function readNativeFirebaseConfig(projectRoot) {
32231
32277
  "app.config.ts",
32232
32278
  "app.config.cjs",
32233
32279
  "app.config.mjs"
32234
- ].some((name2) => import_node_fs18.default.existsSync(import_node_path19.default.join(projectRoot, name2))))
32280
+ ].some((name2) => import_node_fs19.default.existsSync(import_node_path20.default.join(projectRoot, name2))))
32235
32281
  return result;
32236
- const require5 = (0, import_node_module.createRequire)(import_node_path19.default.join(projectRoot, "package.json"));
32282
+ const require5 = (0, import_node_module.createRequire)(import_node_path20.default.join(projectRoot, "package.json"));
32237
32283
  const configModule = require5("@expo/config");
32238
32284
  if (!isRecord(configModule) || typeof configModule.getConfig !== "function") {
32239
32285
  throw new Error("Expo native configuration is unavailable.");
@@ -32247,8 +32293,8 @@ function readNativeFirebaseConfig(projectRoot) {
32247
32293
  const native = config[platform];
32248
32294
  if (!isRecord(native) || typeof native.googleServicesFile !== "string") continue;
32249
32295
  try {
32250
- const source = import_node_fs18.default.readFileSync(
32251
- import_node_path19.default.resolve(projectRoot, native.googleServicesFile),
32296
+ const source = import_node_fs19.default.readFileSync(
32297
+ import_node_path20.default.resolve(projectRoot, native.googleServicesFile),
32252
32298
  "utf8"
32253
32299
  );
32254
32300
  const parsed = platform === "ios" ? parsePlistSource(source) : JSON.parse(source);
@@ -32300,13 +32346,13 @@ function readNativeFirebaseConfig(projectRoot) {
32300
32346
  }
32301
32347
  return result;
32302
32348
  }
32303
- var import_node_fs18, import_node_module, import_node_path19;
32349
+ var import_node_fs19, import_node_module, import_node_path20;
32304
32350
  var init_native_firebase_config = __esm({
32305
32351
  "src/native-firebase-config.ts"() {
32306
32352
  "use strict";
32307
- import_node_fs18 = __toESM(require("node:fs"), 1);
32353
+ import_node_fs19 = __toESM(require("node:fs"), 1);
32308
32354
  import_node_module = require("node:module");
32309
- import_node_path19 = __toESM(require("node:path"), 1);
32355
+ import_node_path20 = __toESM(require("node:path"), 1);
32310
32356
  init_is_record();
32311
32357
  init_plist();
32312
32358
  }
@@ -32325,15 +32371,15 @@ function normalizeProfileId(input) {
32325
32371
  return id;
32326
32372
  }
32327
32373
  function profileIndexPath() {
32328
- return import_path5.default.join(profilesDir(), PROFILE_INDEX_FILE);
32374
+ return import_path4.default.join(profilesDir(), PROFILE_INDEX_FILE);
32329
32375
  }
32330
32376
  function playwrightProfileUserDataDir(profileId) {
32331
- return import_path5.default.join(profilesDir(), "playwright", normalizeProfileId(profileId));
32377
+ return import_path4.default.join(profilesDir(), "playwright", normalizeProfileId(profileId));
32332
32378
  }
32333
32379
  function readIndexRaw() {
32334
32380
  try {
32335
32381
  const parsed = JSON.parse(
32336
- import_fs6.default.readFileSync(profileIndexPath(), "utf8")
32382
+ import_fs5.default.readFileSync(profileIndexPath(), "utf8")
32337
32383
  );
32338
32384
  if (!parsed || parsed.version !== PROFILE_INDEX_VERSION) {
32339
32385
  return { version: PROFILE_INDEX_VERSION, profiles: [] };
@@ -32374,9 +32420,9 @@ function writeIndex(index) {
32374
32420
  ensureRnxHome();
32375
32421
  const next = withDefault(index);
32376
32422
  const tmp = `${profileIndexPath()}.tmp`;
32377
- import_fs6.default.writeFileSync(tmp, `${JSON.stringify(next, null, 2)}
32423
+ import_fs5.default.writeFileSync(tmp, `${JSON.stringify(next, null, 2)}
32378
32424
  `, "utf8");
32379
- import_fs6.default.renameSync(tmp, profileIndexPath());
32425
+ import_fs5.default.renameSync(tmp, profileIndexPath());
32380
32426
  return next;
32381
32427
  }
32382
32428
  function listProfiles() {
@@ -32403,12 +32449,12 @@ function createProfile(id) {
32403
32449
  writeIndex({ version: PROFILE_INDEX_VERSION, profiles: [...index.profiles, profile] });
32404
32450
  return profile;
32405
32451
  }
32406
- var import_fs6, import_path5, DEFAULT_PROFILE_ID, PROFILE_INDEX_FILE, PROFILE_INDEX_VERSION;
32452
+ var import_fs5, import_path4, DEFAULT_PROFILE_ID, PROFILE_INDEX_FILE, PROFILE_INDEX_VERSION;
32407
32453
  var init_profiles = __esm({
32408
32454
  "src/profiles.ts"() {
32409
32455
  "use strict";
32410
- import_fs6 = __toESM(require("fs"), 1);
32411
- import_path5 = __toESM(require("path"), 1);
32456
+ import_fs5 = __toESM(require("fs"), 1);
32457
+ import_path4 = __toESM(require("path"), 1);
32412
32458
  init_home_paths();
32413
32459
  DEFAULT_PROFILE_ID = "default";
32414
32460
  PROFILE_INDEX_FILE = "profiles.json";
@@ -32518,59 +32564,59 @@ var init_bundleAssets = __esm({
32518
32564
  // cli/app-catalog.ts
32519
32565
  function listDir(dir) {
32520
32566
  try {
32521
- return import_node_fs19.default.readdirSync(dir, { withFileTypes: true });
32567
+ return import_node_fs20.default.readdirSync(dir, { withFileTypes: true });
32522
32568
  } catch {
32523
32569
  return [];
32524
32570
  }
32525
32571
  }
32526
32572
  function readText(file) {
32527
32573
  try {
32528
- return import_node_fs19.default.readFileSync(file, "utf8");
32574
+ return import_node_fs20.default.readFileSync(file, "utf8");
32529
32575
  } catch {
32530
32576
  return null;
32531
32577
  }
32532
32578
  }
32533
32579
  function catalogFiles(dir, found) {
32534
32580
  for (const entry of listDir(dir)) {
32535
- const full = import_node_path20.default.join(dir, entry.name);
32581
+ const full = import_node_path21.default.join(dir, entry.name);
32536
32582
  if (entry.isDirectory()) catalogFiles(full, found);
32537
32583
  else if (entry.name === "Contents.json") found.push(full);
32538
32584
  }
32539
32585
  }
32540
32586
  function discoverAppCatalog(appDir) {
32541
- const iosDir = import_node_path20.default.join(appDir, "ios");
32587
+ const iosDir = import_node_path21.default.join(appDir, "ios");
32542
32588
  const target = listDir(iosDir).find(
32543
- (entry) => entry.isDirectory() && entry.name !== "Pods" && listDir(import_node_path20.default.join(iosDir, entry.name)).some(
32589
+ (entry) => entry.isDirectory() && entry.name !== "Pods" && listDir(import_node_path21.default.join(iosDir, entry.name)).some(
32544
32590
  (file) => /^AppDelegate\.(swift|mm|m)$/.test(file.name)
32545
32591
  )
32546
32592
  );
32547
32593
  if (!target) return null;
32548
- const targetDir = import_node_path20.default.join(iosDir, target.name);
32594
+ const targetDir = import_node_path21.default.join(iosDir, target.name);
32549
32595
  const files = [];
32550
32596
  for (const entry of listDir(targetDir)) {
32551
32597
  if (entry.isDirectory() && entry.name.endsWith(".xcassets"))
32552
- catalogFiles(import_node_path20.default.join(targetDir, entry.name), files);
32598
+ catalogFiles(import_node_path21.default.join(targetDir, entry.name), files);
32553
32599
  }
32554
32600
  const relative2 = files.map(
32555
- (file) => import_node_path20.default.relative(targetDir, file).split(import_node_path20.default.sep).join(import_node_path20.default.posix.sep)
32601
+ (file) => import_node_path21.default.relative(targetDir, file).split(import_node_path21.default.sep).join(import_node_path21.default.posix.sep)
32556
32602
  );
32557
32603
  const colors = enumerateBundleColors(
32558
32604
  relative2,
32559
- (candidate) => candidate.endsWith("Contents.json") ? readText(import_node_path20.default.join(targetDir, candidate)) : null
32605
+ (candidate) => candidate.endsWith("Contents.json") ? readText(import_node_path21.default.join(targetDir, candidate)) : null
32560
32606
  );
32561
32607
  const pbxproj = listDir(iosDir).find((entry) => entry.name.endsWith(".xcodeproj"));
32562
- const accentName = readText(import_node_path20.default.join(targetDir, "Info.plist"))?.match(PLIST_ACCENT)?.[1] ?? (pbxproj ? readText(import_node_path20.default.join(iosDir, pbxproj.name, "project.pbxproj"))?.match(
32608
+ const accentName = readText(import_node_path21.default.join(targetDir, "Info.plist"))?.match(PLIST_ACCENT)?.[1] ?? (pbxproj ? readText(import_node_path21.default.join(iosDir, pbxproj.name, "project.pbxproj"))?.match(
32563
32609
  ACCENT_BUILD_SETTING
32564
32610
  )?.[1] : void 0) ?? null;
32565
32611
  if (accentName === null && Object.keys(colors).length === 0) return null;
32566
32612
  return { colors, accentName };
32567
32613
  }
32568
- var import_node_fs19, import_node_path20, ACCENT_BUILD_SETTING, PLIST_ACCENT;
32614
+ var import_node_fs20, import_node_path21, ACCENT_BUILD_SETTING, PLIST_ACCENT;
32569
32615
  var init_app_catalog = __esm({
32570
32616
  "cli/app-catalog.ts"() {
32571
32617
  "use strict";
32572
- import_node_fs19 = __toESM(require("node:fs"), 1);
32573
- import_node_path20 = __toESM(require("node:path"), 1);
32618
+ import_node_fs20 = __toESM(require("node:fs"), 1);
32619
+ import_node_path21 = __toESM(require("node:path"), 1);
32574
32620
  init_bundleAssets();
32575
32621
  ACCENT_BUILD_SETTING = /ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "?([^";]+)"?;/;
32576
32622
  PLIST_ACCENT = /<key>NSAccentColorName<\/key>\s*<string>([^<]+)<\/string>/;
@@ -32580,9 +32626,9 @@ var init_app_catalog = __esm({
32580
32626
  // cli/app-project.ts
32581
32627
  function firstNamedFile(dir, names) {
32582
32628
  for (const name2 of names) {
32583
- const candidate = import_node_path21.default.join(dir, name2);
32629
+ const candidate = import_node_path22.default.join(dir, name2);
32584
32630
  try {
32585
- if (import_node_fs20.default.statSync(candidate).isFile()) return candidate;
32631
+ if (import_node_fs21.default.statSync(candidate).isFile()) return candidate;
32586
32632
  } catch {
32587
32633
  }
32588
32634
  }
@@ -32595,24 +32641,24 @@ function findRNXAppConfig(dir) {
32595
32641
  return firstNamedFile(dir, RNX_APP_CONFIG_NAMES);
32596
32642
  }
32597
32643
  function resolveAppProject(projectRoot) {
32598
- const appDir = import_node_path21.default.resolve(projectRoot);
32644
+ const appDir = import_node_path22.default.resolve(projectRoot);
32599
32645
  try {
32600
- if (!import_node_fs20.default.statSync(appDir).isDirectory()) return null;
32646
+ if (!import_node_fs21.default.statSync(appDir).isDirectory()) return null;
32601
32647
  } catch {
32602
32648
  return null;
32603
32649
  }
32604
32650
  const configPath = findRNXAppConfig(appDir);
32605
- if (!configPath && !findExpoAppConfig(appDir) && !import_node_fs20.default.existsSync(import_node_path21.default.join(appDir, "package.json"))) {
32651
+ if (!configPath && !findExpoAppConfig(appDir) && !import_node_fs21.default.existsSync(import_node_path22.default.join(appDir, "package.json"))) {
32606
32652
  return null;
32607
32653
  }
32608
32654
  return { appDir, configPath };
32609
32655
  }
32610
- var import_node_fs20, import_node_path21, EXPO_APP_CONFIG_NAMES, RNX_APP_CONFIG_NAMES;
32656
+ var import_node_fs21, import_node_path22, EXPO_APP_CONFIG_NAMES, RNX_APP_CONFIG_NAMES;
32611
32657
  var init_app_project = __esm({
32612
32658
  "cli/app-project.ts"() {
32613
32659
  "use strict";
32614
- import_node_fs20 = __toESM(require("node:fs"), 1);
32615
- import_node_path21 = __toESM(require("node:path"), 1);
32660
+ import_node_fs21 = __toESM(require("node:fs"), 1);
32661
+ import_node_path22 = __toESM(require("node:path"), 1);
32616
32662
  EXPO_APP_CONFIG_NAMES = [
32617
32663
  "app.config.js",
32618
32664
  "app.config.ts",
@@ -32641,13 +32687,13 @@ function isRNXConfig(value) {
32641
32687
  }
32642
32688
  function resolveConfigReplacementFiles(config, configPath) {
32643
32689
  if (!config.modules) return config;
32644
- const configDir = import_node_path22.default.dirname(configPath);
32690
+ const configDir = import_node_path23.default.dirname(configPath);
32645
32691
  return {
32646
32692
  ...config,
32647
32693
  modules: Object.fromEntries(
32648
32694
  Object.entries(config.modules).map(([name2, resolution]) => [
32649
32695
  name2,
32650
- resolution && typeof resolution === "object" && "file" in resolution ? { ...resolution, file: import_node_path22.default.resolve(configDir, resolution.file) } : resolution
32696
+ resolution && typeof resolution === "object" && "file" in resolution ? { ...resolution, file: import_node_path23.default.resolve(configDir, resolution.file) } : resolution
32651
32697
  ])
32652
32698
  )
32653
32699
  };
@@ -32677,12 +32723,12 @@ async function resolveRNXAppConfig(startDir = process.cwd()) {
32677
32723
  const project = resolveAppProject(startDir);
32678
32724
  return { project, config: await loadRNXAppConfig(project) };
32679
32725
  }
32680
- var import_node_module2, import_node_path22, import_jiti, require2;
32726
+ var import_node_module2, import_node_path23, import_jiti, require2;
32681
32727
  var init_app_config = __esm({
32682
32728
  "cli/app-config.ts"() {
32683
32729
  "use strict";
32684
32730
  import_node_module2 = require("node:module");
32685
- import_node_path22 = __toESM(require("node:path"), 1);
32731
+ import_node_path23 = __toESM(require("node:path"), 1);
32686
32732
  init_src();
32687
32733
  import_jiti = require("jiti");
32688
32734
  init_public_brand();
@@ -32739,13 +32785,13 @@ function discoverNativeLinkedAppFonts(opts) {
32739
32785
  scannedFontDirectories++;
32740
32786
  let entries;
32741
32787
  try {
32742
- entries = import_node_fs21.default.readdirSync(current.dir, { withFileTypes: true });
32788
+ entries = import_node_fs22.default.readdirSync(current.dir, { withFileTypes: true });
32743
32789
  } catch {
32744
32790
  continue;
32745
32791
  }
32746
32792
  for (const entry of entries) {
32747
32793
  if (entry.isSymbolicLink()) continue;
32748
- const fullPath = import_node_path23.default.join(current.dir, entry.name);
32794
+ const fullPath = import_node_path24.default.join(current.dir, entry.name);
32749
32795
  if (entry.isDirectory()) {
32750
32796
  if (current.depth < 4 && pending.length < 64 && !entry.name.startsWith(".")) {
32751
32797
  pending.push({ dir: fullPath, depth: current.depth + 1 });
@@ -32753,15 +32799,15 @@ function discoverNativeLinkedAppFonts(opts) {
32753
32799
  continue;
32754
32800
  }
32755
32801
  if (!entry.isFile() || !/\.(ttf|otf|woff|woff2)$/i.test(entry.name)) continue;
32756
- const relative2 = import_node_path23.default.relative(root, fullPath).split(import_node_path23.default.sep).join("/");
32757
- fontPaths.push(import_node_path23.default.posix.join(metroPathPrefix, relative2));
32802
+ const relative2 = import_node_path24.default.relative(root, fullPath).split(import_node_path24.default.sep).join("/");
32803
+ fontPaths.push(import_node_path24.default.posix.join(metroPathPrefix, relative2));
32758
32804
  if (fontPaths.length >= 256) break;
32759
32805
  }
32760
32806
  }
32761
32807
  };
32762
32808
  try {
32763
32809
  const packageJson = JSON.parse(
32764
- import_node_fs21.default.readFileSync(import_node_path23.default.join(selectedAppDir, "package.json"), "utf8")
32810
+ import_node_fs22.default.readFileSync(import_node_path24.default.join(selectedAppDir, "package.json"), "utf8")
32765
32811
  );
32766
32812
  const dependencyNames = /* @__PURE__ */ new Set();
32767
32813
  for (const field of ["dependencies", "devDependencies", "optionalDependencies"]) {
@@ -32776,25 +32822,34 @@ function discoverNativeLinkedAppFonts(opts) {
32776
32822
  const config = Reflect.get(packageJson, "reactNativeVectorIcons");
32777
32823
  const configuredFontDir = config && typeof config === "object" ? Reflect.get(config, "fontDir") : null;
32778
32824
  const configuredDir = typeof configuredFontDir === "string" ? configuredFontDir : "rnvi-fonts";
32779
- const root = import_node_path23.default.resolve(selectedAppDir, configuredDir);
32780
- const relativeRoot = import_node_path23.default.relative(selectedAppDir, root);
32781
- if (!relativeRoot.startsWith("..") && !import_node_path23.default.isAbsolute(relativeRoot)) {
32782
- collectFontFiles(root, relativeRoot.split(import_node_path23.default.sep).join("/"));
32783
- }
32784
- const vectorIconRequire = (0, import_node_module3.createRequire)(import_node_path23.default.join(selectedAppDir, "package.json"));
32825
+ const root = import_node_path24.default.resolve(selectedAppDir, configuredDir);
32826
+ const relativeRoot = import_node_path24.default.relative(selectedAppDir, root);
32827
+ if (!relativeRoot.startsWith("..") && !import_node_path24.default.isAbsolute(relativeRoot)) {
32828
+ collectFontFiles(root, relativeRoot.split(import_node_path24.default.sep).join("/"));
32829
+ }
32830
+ const bundleDir = import_node_path24.default.posix.dirname(new URL(opts.bundleUrl).pathname).replace(/^\/+/, "");
32831
+ const appRelativeDir = bundleDir.split("/").join(import_node_path24.default.sep);
32832
+ const metroRootCandidates = [selectedAppDir];
32833
+ if (bundleDir && selectedAppDir.endsWith(import_node_path24.default.sep + appRelativeDir)) {
32834
+ metroRootCandidates.push(selectedAppDir.slice(0, -appRelativeDir.length - 1));
32835
+ }
32836
+ const vectorIconRequire = (0, import_node_module3.createRequire)(import_node_path24.default.join(selectedAppDir, "package.json"));
32785
32837
  for (const dependencyName of vectorIconDependencies) {
32786
32838
  try {
32787
32839
  const entryPath = vectorIconRequire.resolve(dependencyName);
32788
- const dependencyPath = dependencyName.split("/").join(import_node_path23.default.sep);
32789
- const marker = `${import_node_path23.default.sep}node_modules${import_node_path23.default.sep}${dependencyPath}${import_node_path23.default.sep}`;
32840
+ const dependencyPath = dependencyName.split("/").join(import_node_path24.default.sep);
32841
+ const marker = `${import_node_path24.default.sep}node_modules${import_node_path24.default.sep}${dependencyPath}${import_node_path24.default.sep}`;
32790
32842
  const markerIndex = entryPath.lastIndexOf(marker);
32791
32843
  if (markerIndex === -1) continue;
32792
32844
  const packageRoot = entryPath.slice(0, markerIndex + marker.length - 1);
32793
32845
  const fontsDir = dependencyName === "react-native-vector-icons" ? "Fonts" : "fonts";
32794
- collectFontFiles(
32795
- import_node_path23.default.join(packageRoot, fontsDir),
32796
- import_node_path23.default.posix.join("node_modules", dependencyName, fontsDir)
32797
- );
32846
+ const fontsRoot = import_node_path24.default.join(packageRoot, fontsDir);
32847
+ for (const metroRoot of metroRootCandidates) {
32848
+ collectFontFiles(
32849
+ fontsRoot,
32850
+ import_node_path24.default.relative(metroRoot, fontsRoot).split(import_node_path24.default.sep).join("/")
32851
+ );
32852
+ }
32798
32853
  } catch {
32799
32854
  }
32800
32855
  }
@@ -32802,37 +32857,37 @@ function discoverNativeLinkedAppFonts(opts) {
32802
32857
  } catch {
32803
32858
  }
32804
32859
  try {
32805
- const configPath = import_node_path23.default.join(selectedAppDir, "react-native.config.js");
32806
- if (import_node_fs21.default.statSync(configPath).isFile()) {
32807
- const appConfigRequire = (0, import_node_module3.createRequire)(import_node_path23.default.join(selectedAppDir, "package.json"));
32860
+ const configPath = import_node_path24.default.join(selectedAppDir, "react-native.config.js");
32861
+ if (import_node_fs22.default.statSync(configPath).isFile()) {
32862
+ const appConfigRequire = (0, import_node_module3.createRequire)(import_node_path24.default.join(selectedAppDir, "package.json"));
32808
32863
  const rnConfig = appConfigRequire(configPath);
32809
32864
  const assets = rnConfig && typeof rnConfig === "object" ? Reflect.get(rnConfig, "assets") : null;
32810
32865
  if (Array.isArray(assets)) {
32811
32866
  for (const assetDir of assets) {
32812
32867
  if (typeof assetDir !== "string") continue;
32813
- const root = import_node_path23.default.resolve(selectedAppDir, assetDir);
32814
- const relativeRoot = import_node_path23.default.relative(selectedAppDir, root);
32815
- if (relativeRoot.startsWith("..") || import_node_path23.default.isAbsolute(relativeRoot)) continue;
32816
- collectFontFiles(root, relativeRoot.split(import_node_path23.default.sep).join("/"));
32868
+ const root = import_node_path24.default.resolve(selectedAppDir, assetDir);
32869
+ const relativeRoot = import_node_path24.default.relative(selectedAppDir, root);
32870
+ if (relativeRoot.startsWith("..") || import_node_path24.default.isAbsolute(relativeRoot)) continue;
32871
+ collectFontFiles(root, relativeRoot.split(import_node_path24.default.sep).join("/"));
32817
32872
  }
32818
32873
  }
32819
32874
  }
32820
32875
  } catch {
32821
32876
  }
32822
32877
  if (platform === "ios") {
32823
- const iosDir = import_node_path23.default.join(selectedAppDir, "ios");
32878
+ const iosDir = import_node_path24.default.join(selectedAppDir, "ios");
32824
32879
  try {
32825
- const targetDirs = import_node_fs21.default.readdirSync(iosDir, { withFileTypes: true }).filter(
32880
+ const targetDirs = import_node_fs22.default.readdirSync(iosDir, { withFileTypes: true }).filter(
32826
32881
  (entry) => entry.isDirectory() && !entry.isSymbolicLink() && entry.name !== "Pods" && entry.name !== "build" && !entry.name.startsWith(".")
32827
32882
  ).slice(0, 64);
32828
- const plistPaths = [import_node_path23.default.join(iosDir, "Info.plist")];
32883
+ const plistPaths = [import_node_path24.default.join(iosDir, "Info.plist")];
32829
32884
  for (const entry of targetDirs) {
32830
- plistPaths.push(import_node_path23.default.join(iosDir, entry.name, "Info.plist"));
32885
+ plistPaths.push(import_node_path24.default.join(iosDir, entry.name, "Info.plist"));
32831
32886
  }
32832
32887
  for (const plistPath of plistPaths) {
32833
32888
  let parsed;
32834
32889
  try {
32835
- parsed = parsePlistSource(import_node_fs21.default.readFileSync(plistPath, "utf8"));
32890
+ parsed = parsePlistSource(import_node_fs22.default.readFileSync(plistPath, "utf8"));
32836
32891
  } catch {
32837
32892
  continue;
32838
32893
  }
@@ -32842,21 +32897,21 @@ function discoverNativeLinkedAppFonts(opts) {
32842
32897
  for (const declaredFont of declaredFonts) {
32843
32898
  if (typeof declaredFont !== "string") continue;
32844
32899
  const candidates = [
32845
- import_node_path23.default.resolve(import_node_path23.default.dirname(plistPath), declaredFont),
32846
- import_node_path23.default.resolve(iosDir, declaredFont)
32900
+ import_node_path24.default.resolve(import_node_path24.default.dirname(plistPath), declaredFont),
32901
+ import_node_path24.default.resolve(iosDir, declaredFont)
32847
32902
  ];
32848
32903
  const fontPath = candidates.find((candidate) => {
32849
- const relative2 = import_node_path23.default.relative(selectedAppDir, candidate);
32850
- if (relative2.startsWith("..") || import_node_path23.default.isAbsolute(relative2)) return false;
32904
+ const relative2 = import_node_path24.default.relative(selectedAppDir, candidate);
32905
+ if (relative2.startsWith("..") || import_node_path24.default.isAbsolute(relative2)) return false;
32851
32906
  try {
32852
- return import_node_fs21.default.statSync(candidate).isFile();
32907
+ return import_node_fs22.default.statSync(candidate).isFile();
32853
32908
  } catch {
32854
32909
  return false;
32855
32910
  }
32856
32911
  });
32857
32912
  if (!fontPath) continue;
32858
32913
  fontPaths.push(
32859
- import_node_path23.default.relative(selectedAppDir, fontPath).split(import_node_path23.default.sep).join("/")
32914
+ import_node_path24.default.relative(selectedAppDir, fontPath).split(import_node_path24.default.sep).join("/")
32860
32915
  );
32861
32916
  }
32862
32917
  }
@@ -32895,13 +32950,13 @@ async function resolveMetroProjectRoot(bundleUrl, opts) {
32895
32950
  function encodeAppFontsWire(specs) {
32896
32951
  return specs.map((spec) => `${encodeURIComponent(spec.url)}::${encodeURIComponent(spec.family)}`).join(",");
32897
32952
  }
32898
- var import_node_fs21, import_node_module3, import_node_path23, import_config_plugin_fonts, require3;
32953
+ var import_node_fs22, import_node_module3, import_node_path24, import_config_plugin_fonts, require3;
32899
32954
  var init_app_fonts = __esm({
32900
32955
  "cli/app-fonts.ts"() {
32901
32956
  "use strict";
32902
- import_node_fs21 = __toESM(require("node:fs"), 1);
32957
+ import_node_fs22 = __toESM(require("node:fs"), 1);
32903
32958
  import_node_module3 = require("node:module");
32904
- import_node_path23 = __toESM(require("node:path"), 1);
32959
+ import_node_path24 = __toESM(require("node:path"), 1);
32905
32960
  import_config_plugin_fonts = require("peach-engine/engine/config-plugin-fonts");
32906
32961
  init_dev_server_scanner();
32907
32962
  init_backend_origin();
@@ -33760,7 +33815,7 @@ var init_bridge_diagnostics = __esm({
33760
33815
  function getSootsimRoot() {
33761
33816
  if (_sootsimRoot !== void 0) return _sootsimRoot;
33762
33817
  try {
33763
- _sootsimRoot = (0, import_path6.dirname)(
33818
+ _sootsimRoot = (0, import_path5.dirname)(
33764
33819
  (0, import_url2.fileURLToPath)(import_meta2.resolve("peach-engine/package.json"))
33765
33820
  );
33766
33821
  } catch {
@@ -33771,8 +33826,8 @@ function getSootsimRoot() {
33771
33826
  function findDevElectron() {
33772
33827
  const engineDir = getSootsimRoot();
33773
33828
  if (!engineDir) return null;
33774
- const engineMain = (0, import_path6.join)(engineDir, "dist-electron/main.cjs");
33775
- if (!(0, import_fs7.existsSync)(engineMain)) return null;
33829
+ const engineMain = (0, import_path5.join)(engineDir, "dist-electron/main.cjs");
33830
+ if (!(0, import_fs6.existsSync)(engineMain)) return null;
33776
33831
  const electronBin = findElectronBin(engineDir);
33777
33832
  if (!electronBin) return null;
33778
33833
  return {
@@ -33785,14 +33840,14 @@ function findDevElectron() {
33785
33840
  function isInRepoCheckout() {
33786
33841
  const root = getSootsimRoot();
33787
33842
  if (!root) return false;
33788
- return (0, import_fs7.existsSync)((0, import_path6.join)(root, "src-electron/main.ts"));
33843
+ return (0, import_fs6.existsSync)((0, import_path5.join)(root, "src-electron/main.ts"));
33789
33844
  }
33790
33845
  function findElectronBin(startDir) {
33791
33846
  let dir = startDir;
33792
33847
  for (let i = 0; i < 6; i++) {
33793
- const candidate = (0, import_path6.join)(dir, "node_modules/.bin/electron");
33794
- if ((0, import_fs7.existsSync)(candidate)) return candidate;
33795
- const parent = (0, import_path6.dirname)(dir);
33848
+ const candidate = (0, import_path5.join)(dir, "node_modules/.bin/electron");
33849
+ if ((0, import_fs6.existsSync)(candidate)) return candidate;
33850
+ const parent = (0, import_path5.dirname)(dir);
33796
33851
  if (parent === dir) break;
33797
33852
  dir = parent;
33798
33853
  }
@@ -33801,9 +33856,9 @@ function findElectronBin(startDir) {
33801
33856
  function findInstalledMacApp() {
33802
33857
  const candidates = [
33803
33858
  "/Applications/peach.app",
33804
- (0, import_path6.resolve)(process.env.HOME || "", "Applications/peach.app")
33859
+ (0, import_path5.resolve)(process.env.HOME || "", "Applications/peach.app")
33805
33860
  ];
33806
- const found = candidates.find((candidate) => (0, import_fs7.existsSync)(candidate));
33861
+ const found = candidates.find((candidate) => (0, import_fs6.existsSync)(candidate));
33807
33862
  if (found) {
33808
33863
  return {
33809
33864
  path: found,
@@ -33817,8 +33872,8 @@ function findMacApp() {
33817
33872
  const installed2 = findInstalledMacApp();
33818
33873
  if (installed2) return installed2;
33819
33874
  const root = getSootsimRoot();
33820
- const builtApp = root ? (0, import_path6.resolve)(root, "app/peach.app") : null;
33821
- if (builtApp && (0, import_fs7.existsSync)(builtApp)) {
33875
+ const builtApp = root ? (0, import_path5.resolve)(root, "app/peach.app") : null;
33876
+ if (builtApp && (0, import_fs6.existsSync)(builtApp)) {
33822
33877
  return { path: builtApp, platform: "darwin", kind: "mac-app" };
33823
33878
  }
33824
33879
  try {
@@ -33839,18 +33894,18 @@ function findMacApp() {
33839
33894
  return null;
33840
33895
  }
33841
33896
  function findFirstAppImage(dir) {
33842
- if (!(0, import_fs7.existsSync)(dir)) return null;
33843
- const match = (0, import_fs7.readdirSync)(dir).filter((entry) => entry.startsWith("peach") && entry.endsWith(".AppImage")).sort().reverse()[0];
33844
- return match ? (0, import_path6.join)(dir, match) : null;
33897
+ if (!(0, import_fs6.existsSync)(dir)) return null;
33898
+ const match = (0, import_fs6.readdirSync)(dir).filter((entry) => entry.startsWith("peach") && entry.endsWith(".AppImage")).sort().reverse()[0];
33899
+ return match ? (0, import_path5.join)(dir, match) : null;
33845
33900
  }
33846
33901
  function findInstalledLinuxApp() {
33847
33902
  const directCandidates = [
33848
- (0, import_path6.resolve)(process.env.HOME || "", "Applications/peach.AppImage"),
33849
- (0, import_path6.resolve)(process.env.HOME || "", ".local/bin/peach.AppImage"),
33903
+ (0, import_path5.resolve)(process.env.HOME || "", "Applications/peach.AppImage"),
33904
+ (0, import_path5.resolve)(process.env.HOME || "", ".local/bin/peach.AppImage"),
33850
33905
  "/opt/peach/peach.AppImage",
33851
33906
  "/opt/peach/peach"
33852
33907
  ];
33853
- const directMatch = directCandidates.find((candidate) => (0, import_fs7.existsSync)(candidate));
33908
+ const directMatch = directCandidates.find((candidate) => (0, import_fs6.existsSync)(candidate));
33854
33909
  if (directMatch) {
33855
33910
  return {
33856
33911
  path: directMatch,
@@ -33864,8 +33919,8 @@ function findLinuxInstall() {
33864
33919
  const installed2 = findInstalledLinuxApp();
33865
33920
  if (installed2) return installed2;
33866
33921
  const root = getSootsimRoot();
33867
- const directCandidates = root ? [(0, import_path6.resolve)(root, "app/peach.AppImage"), (0, import_path6.resolve)(root, "release/linux-unpacked/peach")] : [];
33868
- const directMatch = directCandidates.find((candidate) => (0, import_fs7.existsSync)(candidate));
33922
+ const directCandidates = root ? [(0, import_path5.resolve)(root, "app/peach.AppImage"), (0, import_path5.resolve)(root, "release/linux-unpacked/peach")] : [];
33923
+ const directMatch = directCandidates.find((candidate) => (0, import_fs6.existsSync)(candidate));
33869
33924
  if (directMatch) {
33870
33925
  return {
33871
33926
  path: directMatch,
@@ -33873,7 +33928,7 @@ function findLinuxInstall() {
33873
33928
  kind: directMatch.endsWith(".AppImage") ? "linux-appimage" : "linux-binary"
33874
33929
  };
33875
33930
  }
33876
- const scannedMatch = root ? findFirstAppImage((0, import_path6.resolve)(root, "app")) || findFirstAppImage((0, import_path6.resolve)(root, "release")) : null;
33931
+ const scannedMatch = root ? findFirstAppImage((0, import_path5.resolve)(root, "app")) || findFirstAppImage((0, import_path5.resolve)(root, "release")) : null;
33877
33932
  if (!scannedMatch) return null;
33878
33933
  return {
33879
33934
  path: scannedMatch,
@@ -33890,7 +33945,7 @@ function findWindowsInstall() {
33890
33945
  { encoding: "utf8", timeout: 3e3 }
33891
33946
  );
33892
33947
  const executable = /"([^"\r\n]+\.exe)"/i.exec(output)?.[1];
33893
- if (executable && (0, import_fs7.existsSync)(executable)) {
33948
+ if (executable && (0, import_fs6.existsSync)(executable)) {
33894
33949
  return { path: executable, platform: "win32", kind: "win-exe" };
33895
33950
  }
33896
33951
  } catch {
@@ -33903,8 +33958,8 @@ function findDesktopCompanion() {
33903
33958
  if (dev) return dev;
33904
33959
  if (isInRepoCheckout()) {
33905
33960
  const engineDir = getSootsimRoot();
33906
- const engineMain = (0, import_path6.join)(engineDir, "dist-electron/main.cjs");
33907
- if (!(0, import_fs7.existsSync)(engineMain)) {
33961
+ const engineMain = (0, import_path5.join)(engineDir, "dist-electron/main.cjs");
33962
+ if (!(0, import_fs6.existsSync)(engineMain)) {
33908
33963
  console.error(
33909
33964
  ` dist-electron/main.cjs missing in ${engineDir}.
33910
33965
  run: bun run --cwd packages/peach-engine build:electron-main
@@ -33975,13 +34030,13 @@ function buildMacLaunchUrl(url, opts) {
33975
34030
  }
33976
34031
  return deepLink.toString();
33977
34032
  }
33978
- var import_child_process5, import_fs7, import_path6, import_url2, import_meta2, _sootsimRoot, PEACH_BUNDLE_ID;
34033
+ var import_child_process5, import_fs6, import_path5, import_url2, import_meta2, _sootsimRoot, PEACH_BUNDLE_ID;
33979
34034
  var init_desktop_companion = __esm({
33980
34035
  "cli/desktop-companion.ts"() {
33981
34036
  "use strict";
33982
34037
  import_child_process5 = require("child_process");
33983
- import_fs7 = require("fs");
33984
- import_path6 = require("path");
34038
+ import_fs6 = require("fs");
34039
+ import_path5 = require("path");
33985
34040
  import_url2 = require("url");
33986
34041
  import_meta2 = {};
33987
34042
  PEACH_BUNDLE_ID = "dev.peachsim.simulator";
@@ -34089,7 +34144,7 @@ function resolvePlaywright() {
34089
34144
  try {
34090
34145
  const modulePath = requireFromRoot.resolve(spec);
34091
34146
  const packageJsonPath = requireFromRoot.resolve(`${spec}/package.json`);
34092
- const parsed = JSON.parse((0, import_node_fs22.readFileSync)(packageJsonPath, "utf8"));
34147
+ const parsed = JSON.parse((0, import_node_fs23.readFileSync)(packageJsonPath, "utf8"));
34093
34148
  if (!isRecord(parsed) || typeof parsed.version !== "string") continue;
34094
34149
  const bin = parsed.bin;
34095
34150
  let binPath = null;
@@ -34101,8 +34156,8 @@ function resolvePlaywright() {
34101
34156
  binPath = typeof named === "string" ? named : typeof first === "string" ? first : null;
34102
34157
  }
34103
34158
  if (!binPath) continue;
34104
- const cliPath = (0, import_node_path24.join)((0, import_node_path24.dirname)(packageJsonPath), binPath);
34105
- if (!(0, import_node_fs22.existsSync)(cliPath)) continue;
34159
+ const cliPath = (0, import_node_path25.join)((0, import_node_path25.dirname)(packageJsonPath), binPath);
34160
+ if (!(0, import_node_fs23.existsSync)(cliPath)) continue;
34106
34161
  return {
34107
34162
  spec,
34108
34163
  modulePath,
@@ -34146,7 +34201,7 @@ function probeBrowser(resolved, env) {
34146
34201
  return {
34147
34202
  ok: true,
34148
34203
  executablePath: parsed.executablePath,
34149
- exists: parsed.exists && (0, import_node_fs22.existsSync)(parsed.executablePath)
34204
+ exists: parsed.exists && (0, import_node_fs23.existsSync)(parsed.executablePath)
34150
34205
  };
34151
34206
  } catch (error) {
34152
34207
  return {
@@ -34197,14 +34252,14 @@ ${detail}` : ""}`
34197
34252
  }
34198
34253
  return { ok: true, executablePath: after.executablePath, installed: true };
34199
34254
  }
34200
- var import_node_child_process6, import_node_fs22, import_node_module5, import_node_path24;
34255
+ var import_node_child_process6, import_node_fs23, import_node_module5, import_node_path25;
34201
34256
  var init_playwright_provisioning = __esm({
34202
34257
  "cli/drivers/playwright-provisioning.ts"() {
34203
34258
  "use strict";
34204
34259
  import_node_child_process6 = require("node:child_process");
34205
- import_node_fs22 = require("node:fs");
34260
+ import_node_fs23 = require("node:fs");
34206
34261
  import_node_module5 = require("node:module");
34207
- import_node_path24 = require("node:path");
34262
+ import_node_path25 = require("node:path");
34208
34263
  init_is_record();
34209
34264
  init_internal_child();
34210
34265
  init_self_invocation();
@@ -34240,7 +34295,7 @@ function resolveUserDataDir(opts) {
34240
34295
  return playwrightProfileUserDataDir(ensureProfile(opts.profileId).id);
34241
34296
  }
34242
34297
  if (opts.ephemeralProfile) {
34243
- return (0, import_fs8.mkdtempSync)((0, import_path7.join)((0, import_os2.tmpdir)(), "peach-playwright-profile-"));
34298
+ return (0, import_fs7.mkdtempSync)((0, import_path6.join)((0, import_os2.tmpdir)(), "peach-playwright-profile-"));
34244
34299
  }
34245
34300
  return "";
34246
34301
  }
@@ -34270,9 +34325,9 @@ async function launch2(opts) {
34270
34325
  message: `playwright browser provisioning failed: ${provisioning.message}`
34271
34326
  };
34272
34327
  }
34273
- const errLog = (0, import_path7.join)((0, import_os2.tmpdir)(), playwrightHostLogName(Date.now(), process.pid));
34328
+ const errLog = (0, import_path6.join)((0, import_os2.tmpdir)(), playwrightHostLogName(Date.now(), process.pid));
34274
34329
  const connectAckFile = `${errLog}.connected`;
34275
- const errFd = (0, import_fs8.openSync)(errLog, "a");
34330
+ const errFd = (0, import_fs7.openSync)(errLog, "a");
34276
34331
  try {
34277
34332
  const self = rnxSelfInvocation();
34278
34333
  const child = (0, import_child_process6.spawn)(
@@ -34308,7 +34363,7 @@ async function launch2(opts) {
34308
34363
  });
34309
34364
  });
34310
34365
  if (earlyExit !== null) {
34311
- const detail = (0, import_fs8.readFileSync)(errLog, "utf8").trim();
34366
+ const detail = (0, import_fs7.readFileSync)(errLog, "utf8").trim();
34312
34367
  const hint = headlessHintForLinuxFailure(opts, detail);
34313
34368
  return {
34314
34369
  launched: false,
@@ -34335,17 +34390,17 @@ ${hint}` : ""}`
34335
34390
  message: `playwright launch failed: ${err instanceof Error ? err.message : String(err)}`
34336
34391
  };
34337
34392
  } finally {
34338
- (0, import_fs8.closeSync)(errFd);
34393
+ (0, import_fs7.closeSync)(errFd);
34339
34394
  }
34340
34395
  }
34341
- var import_child_process6, import_fs8, import_os2, import_path7, playwrightDriver;
34396
+ var import_child_process6, import_fs7, import_os2, import_path6, playwrightDriver;
34342
34397
  var init_playwright = __esm({
34343
34398
  "cli/drivers/playwright.ts"() {
34344
34399
  "use strict";
34345
34400
  import_child_process6 = require("child_process");
34346
- import_fs8 = require("fs");
34401
+ import_fs7 = require("fs");
34347
34402
  import_os2 = require("os");
34348
- import_path7 = require("path");
34403
+ import_path6 = require("path");
34349
34404
  init_bridge_constants();
34350
34405
  init_playwright_host_log();
34351
34406
  init_profiles();
@@ -34412,6 +34467,264 @@ var init_env = __esm({
34412
34467
  }
34413
34468
  });
34414
34469
 
34470
+ // cli/ui.ts
34471
+ var init_ui = __esm({
34472
+ "cli/ui.ts"() {
34473
+ "use strict";
34474
+ }
34475
+ });
34476
+
34477
+ // cli/prompt.ts
34478
+ var init_prompt = __esm({
34479
+ "cli/prompt.ts"() {
34480
+ "use strict";
34481
+ init_ui();
34482
+ }
34483
+ });
34484
+
34485
+ // cli/privacy.ts
34486
+ function diagnosticsAllowedForCurrentProcess(preferences = readPrivacyPreferences()) {
34487
+ const doNotTrack = process.env.DO_NOT_TRACK;
34488
+ if (doNotTrack === "1" || doNotTrack === "true") return false;
34489
+ return preferences.configured && preferences.productAnalytics;
34490
+ }
34491
+ var init_privacy = __esm({
34492
+ "cli/privacy.ts"() {
34493
+ "use strict";
34494
+ init_home_paths();
34495
+ init_env();
34496
+ init_prompt();
34497
+ }
34498
+ });
34499
+
34500
+ // cli/command-registry.ts
34501
+ var NODE_COMMAND_NAMES, BROWSER_FAMILIES, registrations, RNX_COMMAND_NAMES, RNX_NODE_COMMAND_NAMES;
34502
+ var init_command_registry = __esm({
34503
+ "cli/command-registry.ts"() {
34504
+ "use strict";
34505
+ NODE_COMMAND_NAMES = [
34506
+ "test",
34507
+ "detox",
34508
+ "maestro",
34509
+ "record",
34510
+ "film",
34511
+ "storage",
34512
+ "permissions",
34513
+ "perf",
34514
+ "screenshot",
34515
+ "state",
34516
+ "reset",
34517
+ "camera",
34518
+ "mode",
34519
+ "debug",
34520
+ "timeline",
34521
+ "what-happened",
34522
+ "shell",
34523
+ "assert",
34524
+ "device",
34525
+ "open",
34526
+ "ios",
34527
+ "android",
34528
+ "remote",
34529
+ "preview",
34530
+ "box",
34531
+ "list",
34532
+ "use",
34533
+ "claim",
34534
+ "close",
34535
+ "compat",
34536
+ "project-report",
34537
+ "report-issue",
34538
+ "desktop",
34539
+ "login",
34540
+ "logout",
34541
+ "auth",
34542
+ "cli",
34543
+ "setup",
34544
+ "serve",
34545
+ "daemon",
34546
+ "runtime",
34547
+ "upgrade",
34548
+ "version",
34549
+ "skill",
34550
+ "config",
34551
+ "cleanup",
34552
+ "app-fonts",
34553
+ "agent-wrapper",
34554
+ "agent",
34555
+ "describe",
34556
+ "find",
34557
+ "get",
34558
+ "do",
34559
+ "wait",
34560
+ "network",
34561
+ "logs"
34562
+ ];
34563
+ BROWSER_FAMILIES = /* @__PURE__ */ new Map([
34564
+ ["web", "preview"],
34565
+ ["ios", "preview"],
34566
+ ["android", "preview"],
34567
+ ["list", "runtime"],
34568
+ ["use", "runtime"],
34569
+ ["state", "runtime"],
34570
+ ["describe", "tree"],
34571
+ ["find", "find"],
34572
+ ["get", "runtime"],
34573
+ ["wait", "wait"],
34574
+ ["do", "action"],
34575
+ ["shell", "action"],
34576
+ ["reset", "action"],
34577
+ ["screenshot", "screenshot"],
34578
+ ["logs", "logs"],
34579
+ ["network", "network"],
34580
+ ["storage", "storage"],
34581
+ ["timeline", "history"],
34582
+ ["what-happened", "history"],
34583
+ ["assert", "evidence"],
34584
+ ["debug", "evidence"],
34585
+ ["perf", "evidence"]
34586
+ ]);
34587
+ registrations = [
34588
+ .../* @__PURE__ */ new Set([...NODE_COMMAND_NAMES, "web"])
34589
+ ].map((name2) => ({
34590
+ name: name2,
34591
+ node: name2 !== "web",
34592
+ browserFamily: BROWSER_FAMILIES.get(name2) ?? null
34593
+ }));
34594
+ RNX_COMMAND_NAMES = new Set(registrations.map((entry) => entry.name));
34595
+ RNX_NODE_COMMAND_NAMES = new Set(NODE_COMMAND_NAMES);
34596
+ }
34597
+ });
34598
+
34599
+ // cli/parse-args.ts
34600
+ var GLOBAL_FLAGS, GLOBAL_FLAG_TAKES_VALUE, COMMANDS;
34601
+ var init_parse_args = __esm({
34602
+ "cli/parse-args.ts"() {
34603
+ "use strict";
34604
+ init_command_registry();
34605
+ GLOBAL_FLAGS = {
34606
+ "--help": { type: "boolean", short: "-h" },
34607
+ "--version": { type: "boolean", short: "-V" },
34608
+ "--verbose": { type: "boolean", short: "-v" },
34609
+ "--port": { type: "number", short: "-p" },
34610
+ "--device": { type: "string", short: "-d" },
34611
+ "--theme": { type: "string", short: "-t" },
34612
+ "--headless": { type: "boolean" },
34613
+ "--driver": { type: "string" },
34614
+ "--sim": { type: "string" },
34615
+ // documented aliases for --sim (CLAUDE.md / skills / engine docs say
34616
+ // `--session <id>`). normalized to the sim target in bin.ts.
34617
+ "--session": { type: "string" },
34618
+ "--tab": { type: "string" }
34619
+ };
34620
+ GLOBAL_FLAG_TAKES_VALUE = new Map(
34621
+ Object.entries(GLOBAL_FLAGS).flatMap(([name2, def]) => {
34622
+ const takesValue = def.type !== "boolean";
34623
+ return def.short ? [
34624
+ [name2, takesValue],
34625
+ [def.short, takesValue]
34626
+ ] : [[name2, takesValue]];
34627
+ })
34628
+ );
34629
+ COMMANDS = new Set(RNX_NODE_COMMAND_NAMES);
34630
+ }
34631
+ });
34632
+
34633
+ // cli/telemetry.ts
34634
+ function sanitizeDiagnosticMessage(value) {
34635
+ const firstLine = value.slice(0, 2048).split(/[\r\n\u2028\u2029]/, 1)[0] ?? "";
34636
+ return firstLine.split((0, import_node_os3.homedir)()).join("<home>").replace(
34637
+ /<package:(?:@[\w.-]+\/)?[\w.-]+>|(?:https?:\/\/|file:\/\/|[A-Za-z]:[\\/]|<home>[\\/]|\/|\.{1,2}[\\/]|\b[\w.-]+[\\/])[^\s"'<>]+/g,
34638
+ (location2) => {
34639
+ if (location2.startsWith("<package:")) return location2;
34640
+ const dependency = /(?:^|[\\/])node_modules[\\/]((?:@[^\\/]+[\\/])?[^\\/]+)/.exec(
34641
+ location2
34642
+ );
34643
+ return dependency ? `<package:${dependency[1]?.replace(/\\/g, "/")}>` : "<path>";
34644
+ }
34645
+ ).replace(/\b[\w.-]+\.(?:tsx?|jsx?|swift|m|mm|kt|java)(?::\d+(?::\d+)?)?/g, "<source>").replace(/\{.*$|\[(?:\s*["'{\d]|$).*$/g, "<data>").replace(
34646
+ /\b(?:const|let|var)\s+\w+\s*=.*$|\b(?:function|class)\s+\w+.*$|\b(?:import|export)\s+.*$|\breturn\s*[({<].*$/g,
34647
+ "<source>"
34648
+ ).replace(/^\s*at\s+.*$|\bat\s+[\w.$<>]+\s*\([^)]*\)/g, "<stack>").trim().slice(0, 300);
34649
+ }
34650
+ function diagnosticVersion(version) {
34651
+ return version && version.length <= 80 && /^\d+\.\d+\.\d+(?:-[\w.-]+)?$/.test(version) ? version : null;
34652
+ }
34653
+ function setDiagnosticRuntimeVersion(version) {
34654
+ observedRuntimeVersion = diagnosticVersion(version);
34655
+ }
34656
+ function trackCliDiagnostic(diagnostic) {
34657
+ if (!diagnosticsAllowedForCurrentProcess()) return;
34658
+ if (queue.length >= 50) return;
34659
+ const entry = diagnostic.kind === "package_incompatibility" ? diagnostic : { ...diagnostic, message: sanitizeDiagnosticMessage(diagnostic.message) };
34660
+ if (queue.some((queued) => JSON.stringify(queued) === JSON.stringify(entry))) return;
34661
+ queue.push(entry);
34662
+ }
34663
+ var import_node_os3, observedRuntimeVersion, queue;
34664
+ var init_telemetry = __esm({
34665
+ "cli/telemetry.ts"() {
34666
+ "use strict";
34667
+ import_node_os3 = require("node:os");
34668
+ init_cli_version();
34669
+ init_home_paths();
34670
+ init_parse_args();
34671
+ init_privacy();
34672
+ observedRuntimeVersion = null;
34673
+ queue = [];
34674
+ }
34675
+ });
34676
+
34677
+ // cli/runtime-diagnostics.ts
34678
+ async function collectRuntimeDiagnostics(bridge) {
34679
+ if (!diagnosticsAllowedForCurrentProcess()) return;
34680
+ try {
34681
+ const result = await bridge.send(
34682
+ {
34683
+ type: "evaluate",
34684
+ code: `(() => {
34685
+ const messages = []
34686
+ const add = (kind, message) => {
34687
+ if (typeof message === 'string' && message) messages.push({ kind, message: message.slice(0, 2048) })
34688
+ }
34689
+ const obs = window.__sootsimObservability
34690
+ for (const e of (obs?.reportedErrors?.getSnapshot?.() || []).slice(-20)) add('runtime_error', e.message)
34691
+ for (const [kind, entries] of [
34692
+ ['runtime_error', ${consoleEntriesEval("error", 20)}],
34693
+ ['runtime_warning', ${consoleEntriesEval("warn", 20)}],
34694
+ ]) {
34695
+ for (const e of entries) {
34696
+ const parts = e.args.map(a => typeof a === 'string' ? a : typeof a?.message === 'string' ? a.message : '').filter(Boolean)
34697
+ add(kind, parts.join(' '))
34698
+ }
34699
+ }
34700
+ return { runtimeVersion: window.__sootsimRuntimeVersion, messages: messages.slice(0, 50) }
34701
+ })()`
34702
+ },
34703
+ { timeoutMs: 1e3 }
34704
+ );
34705
+ if (!result || typeof result !== "object") return;
34706
+ if ("runtimeVersion" in result && typeof result.runtimeVersion === "string") {
34707
+ setDiagnosticRuntimeVersion(result.runtimeVersion);
34708
+ }
34709
+ if (!("messages" in result) || !Array.isArray(result.messages)) return;
34710
+ for (const entry of result.messages.slice(0, 50)) {
34711
+ if (!entry || typeof entry !== "object") continue;
34712
+ if ((entry.kind === "runtime_error" || entry.kind === "runtime_warning") && typeof entry.message === "string") {
34713
+ trackCliDiagnostic({ kind: entry.kind, message: entry.message });
34714
+ }
34715
+ }
34716
+ } catch {
34717
+ }
34718
+ }
34719
+ var init_runtime_diagnostics = __esm({
34720
+ "cli/runtime-diagnostics.ts"() {
34721
+ "use strict";
34722
+ init_core();
34723
+ init_privacy();
34724
+ init_telemetry();
34725
+ }
34726
+ });
34727
+
34415
34728
  // cli/runtime-notes.ts
34416
34729
  function isChangelogEntry(value) {
34417
34730
  if (!value || typeof value !== "object") return false;
@@ -34667,11 +34980,11 @@ async function runtimeRemove(args) {
34667
34980
  rnxExit(1);
34668
34981
  }
34669
34982
  const dir = runtimeDir(version);
34670
- if (!import_fs9.default.existsSync(dir)) {
34983
+ if (!import_fs8.default.existsSync(dir)) {
34671
34984
  console.error(` ${version} is not installed`);
34672
34985
  return;
34673
34986
  }
34674
- import_fs9.default.rmSync(dir, { recursive: true, force: true });
34987
+ import_fs8.default.rmSync(dir, { recursive: true, force: true });
34675
34988
  console.log(` removed ${version}`);
34676
34989
  }
34677
34990
  async function runtimeWhich() {
@@ -34726,11 +35039,11 @@ function describeError(err) {
34726
35039
  if (err instanceof Error) return err.message;
34727
35040
  return String(err);
34728
35041
  }
34729
- var import_fs9, import_ws3;
35042
+ var import_fs8, import_ws3;
34730
35043
  var init_runtime = __esm({
34731
35044
  "cli/commands/runtime.ts"() {
34732
35045
  "use strict";
34733
- import_fs9 = __toESM(require("fs"), 1);
35046
+ import_fs8 = __toESM(require("fs"), 1);
34734
35047
  init_src();
34735
35048
  import_ws3 = require("ws");
34736
35049
  init_home_paths();
@@ -34873,7 +35186,7 @@ function assertExplicitBridgeLock(preferredPort, explicitPort, lock) {
34873
35186
  async function ensureRuntimeForOpen() {
34874
35187
  if (resolveDevCheckoutRuntimeRoot()) return;
34875
35188
  const active = readActiveRuntime();
34876
- if (active && import_node_fs23.default.existsSync(runtimeDir(active))) return;
35189
+ if (active && import_node_fs24.default.existsSync(runtimeDir(active))) return;
34877
35190
  console.error(" installing peach engine runtime...");
34878
35191
  const { runRuntime: runRuntime2 } = await Promise.resolve().then(() => (init_runtime(), runtime_exports));
34879
35192
  await runRuntime2(["install"], {});
@@ -35027,10 +35340,10 @@ async function buildResolvedBundleOpenUrl(target, baseUrl, opts = {}) {
35027
35340
  }
35028
35341
  function normalizeReplacementPath(filePath) {
35029
35342
  if (filePath.startsWith("~/")) {
35030
- return import_node_path25.default.join(import_node_os3.default.homedir(), filePath.slice(2));
35343
+ return import_node_path26.default.join(import_node_os4.default.homedir(), filePath.slice(2));
35031
35344
  }
35032
- if (import_node_path25.default.isAbsolute(filePath)) return filePath;
35033
- return import_node_path25.default.resolve(process.cwd(), filePath);
35345
+ if (import_node_path26.default.isAbsolute(filePath)) return filePath;
35346
+ return import_node_path26.default.resolve(process.cwd(), filePath);
35034
35347
  }
35035
35348
  function parseOpenRuntimeConfig(args) {
35036
35349
  const modules = {};
@@ -35049,7 +35362,7 @@ function parseOpenRuntimeConfig(args) {
35049
35362
  }
35050
35363
  const moduleName = raw.slice(0, eqIndex).trim();
35051
35364
  const filePath = normalizeReplacementPath(raw.slice(eqIndex + 1).trim());
35052
- if (!import_node_fs23.default.existsSync(filePath)) {
35365
+ if (!import_node_fs24.default.existsSync(filePath)) {
35053
35366
  console.error(` peach open: replacement file not found: ${filePath}`);
35054
35367
  rnxExit(1);
35055
35368
  }
@@ -35080,7 +35393,7 @@ async function resolveAppProjectForBundleUrl(bundleUrl) {
35080
35393
  return advertisedRoot ? resolveAppProject(advertisedRoot) : null;
35081
35394
  }
35082
35395
  async function ensureConfiguredRuntime(version) {
35083
- if (import_node_fs23.default.existsSync(import_node_path25.default.join(runtimeDir(version), "index.html"))) return;
35396
+ if (import_node_fs24.default.existsSync(import_node_path26.default.join(runtimeDir(version), "index.html"))) return;
35084
35397
  console.error(` installing configured engine runtime ${version}...`);
35085
35398
  const result = await rnxRuntime.install({
35086
35399
  version,
@@ -35145,11 +35458,11 @@ async function filterReachableAppFonts(specs) {
35145
35458
  }
35146
35459
  })
35147
35460
  );
35148
- const reachable = [];
35461
+ const reachable = /* @__PURE__ */ new Map();
35149
35462
  for (const spec of results) {
35150
- if (spec !== null) reachable.push(spec);
35463
+ if (spec !== null && !reachable.has(spec.family)) reachable.set(spec.family, spec);
35151
35464
  }
35152
- return reachable;
35465
+ return [...reachable.values()];
35153
35466
  }
35154
35467
  async function resolveShellUrl(target, baseUrl, opts = {}) {
35155
35468
  if (!target) {
@@ -35394,7 +35707,7 @@ function playwrightHostPidForSim(sim) {
35394
35707
  function signalDriverLaunchConnected(result) {
35395
35708
  if (!result.connectAckFile) return false;
35396
35709
  try {
35397
- import_node_fs23.default.writeFileSync(
35710
+ import_node_fs24.default.writeFileSync(
35398
35711
  result.connectAckFile,
35399
35712
  `${JSON.stringify({ connectedAt: Date.now(), pid: result.pid ?? null })}
35400
35713
  `,
@@ -35408,19 +35721,19 @@ function signalDriverLaunchConnected(result) {
35408
35721
  function printDriverDiagnosticLogTail(result) {
35409
35722
  if (!result.diagnosticLogPath) return;
35410
35723
  try {
35411
- const detail = import_node_fs23.default.readFileSync(result.diagnosticLogPath, "utf8").trim();
35724
+ const detail = import_node_fs24.default.readFileSync(result.diagnosticLogPath, "utf8").trim();
35412
35725
  if (!detail) {
35413
- console.error(` ${import_node_path25.default.basename(result.diagnosticLogPath)} was empty`);
35726
+ console.error(` ${import_node_path26.default.basename(result.diagnosticLogPath)} was empty`);
35414
35727
  return;
35415
35728
  }
35416
35729
  const shown = detail.length > 4e3 ? `\u2026
35417
35730
  ${detail.slice(-4e3)}` : detail;
35418
- console.error(` ${import_node_path25.default.basename(result.diagnosticLogPath)}:`);
35731
+ console.error(` ${import_node_path26.default.basename(result.diagnosticLogPath)}:`);
35419
35732
  console.error(shown);
35420
35733
  } catch (err) {
35421
35734
  const message = err instanceof Error ? err.message : String(err);
35422
35735
  console.error(
35423
- ` failed to read ${import_node_path25.default.basename(result.diagnosticLogPath)}: ${message}`
35736
+ ` failed to read ${import_node_path26.default.basename(result.diagnosticLogPath)}: ${message}`
35424
35737
  );
35425
35738
  }
35426
35739
  }
@@ -35541,11 +35854,12 @@ function printAgentListenHint(quiet) {
35541
35854
  }
35542
35855
  }
35543
35856
  async function maybeDescribeAfterOpen(wsPort, simId, args) {
35544
- if (args.includes("--no-describe")) return;
35857
+ const noDescribe = args.includes("--no-describe");
35858
+ if (noDescribe && !diagnosticsAllowedForCurrentProcess()) return;
35545
35859
  const prevQuiet = process.env.SOOTSIM_QUIET_TARGET_NOTICE;
35546
35860
  process.env.SOOTSIM_QUIET_TARGET_NOTICE = "1";
35547
35861
  try {
35548
- await waitForTreeStable(wsPort, simId, { stableMs: 150, maxMs: 400 });
35862
+ if (!noDescribe) await waitForTreeStable(wsPort, simId, { stableMs: 150, maxMs: 400 });
35549
35863
  const bridge = createBridge(wsPort, {
35550
35864
  commandTimeoutMs: 3e3,
35551
35865
  simId,
@@ -35553,6 +35867,7 @@ async function maybeDescribeAfterOpen(wsPort, simId, args) {
35553
35867
  simIdSource: "flag"
35554
35868
  });
35555
35869
  try {
35870
+ if (noDescribe) return;
35556
35871
  let readyProbe = null;
35557
35872
  try {
35558
35873
  readyProbe = await inspectWaitReady(bridge, 1);
@@ -35579,6 +35894,7 @@ async function maybeDescribeAfterOpen(wsPort, simId, args) {
35579
35894
  console.log("");
35580
35895
  console.log(result.tree);
35581
35896
  } finally {
35897
+ await collectRuntimeDiagnostics(bridge);
35582
35898
  bridge.close();
35583
35899
  }
35584
35900
  } catch {
@@ -36350,14 +36666,14 @@ async function runCloseCommand(args, opts = {}) {
36350
36666
  bridge.close();
36351
36667
  }
36352
36668
  }
36353
- var import_node_child_process7, import_node_fs23, import_node_os3, import_node_path25, import_app_catalog_wire, import_devices2, import_ws4, DEFAULT_DRIVER_CONNECT_TIMEOUT_MS, DRIVER_CONNECT_INTERVAL_MS, DRIVER_CONNECT_HOST_GRACE_MS, OPEN_BRIDGE_SPAWN_TIMEOUT_MS, SHELL_APPS, DEV_BUNDLE_RESOLVE_ATTEMPTS, DEV_BUNDLE_RESOLVE_INTERVAL_MS;
36669
+ var import_node_child_process7, import_node_fs24, import_node_os4, import_node_path26, import_app_catalog_wire, import_devices2, import_ws4, DEFAULT_DRIVER_CONNECT_TIMEOUT_MS, DRIVER_CONNECT_INTERVAL_MS, DRIVER_CONNECT_HOST_GRACE_MS, OPEN_BRIDGE_SPAWN_TIMEOUT_MS, SHELL_APPS, DEV_BUNDLE_RESOLVE_ATTEMPTS, DEV_BUNDLE_RESOLVE_INTERVAL_MS;
36354
36670
  var init_control = __esm({
36355
36671
  "cli/commands/control.ts"() {
36356
36672
  "use strict";
36357
36673
  import_node_child_process7 = require("node:child_process");
36358
- import_node_fs23 = __toESM(require("node:fs"), 1);
36359
- import_node_os3 = __toESM(require("node:os"), 1);
36360
- import_node_path25 = __toESM(require("node:path"), 1);
36674
+ import_node_fs24 = __toESM(require("node:fs"), 1);
36675
+ import_node_os4 = __toESM(require("node:os"), 1);
36676
+ import_node_path26 = __toESM(require("node:path"), 1);
36361
36677
  import_app_catalog_wire = require("peach-engine/engine/app-catalog-wire");
36362
36678
  import_devices2 = require("peach-engine/settings/devices");
36363
36679
  import_ws4 = require("ws");
@@ -36385,7 +36701,9 @@ var init_control = __esm({
36385
36701
  init_current_sim();
36386
36702
  init_registry2();
36387
36703
  init_open_url2();
36704
+ init_privacy();
36388
36705
  init_run_rnx();
36706
+ init_runtime_diagnostics();
36389
36707
  init_self_invocation();
36390
36708
  init_ws_bridge();
36391
36709
  init_core();
@@ -37544,17 +37862,17 @@ function normalizeBareStringStep(verb) {
37544
37862
  function parseFlowSteps(content) {
37545
37863
  const parts = content.split(/^---$/m);
37546
37864
  const candidate = parts.length > 1 ? parts[parts.length - 1] : content;
37547
- const parsed = import_yaml.default.parse(candidate);
37865
+ const parsed = import_yaml2.default.parse(candidate);
37548
37866
  return Array.isArray(parsed) ? parsed : [];
37549
37867
  }
37550
- var fs20, path20, import_devices4, import_yaml, import_proof_frame, DEFAULT_TIMEOUT, ASSERTION_LOOKUP_MS, FLOW_TIMEOUT_SCALE, scaledTimeout, MAESTRO_SELECTOR_KEYS, SELECTOR_FILTER_KEYS, UNSUPPORTED_SELECTOR_KEYS, MAESTRO_PERMISSION_KINDS, MAESTRO_PERMISSION_STATUS, SootSimBridgeFlowRunner;
37868
+ var fs20, path20, import_devices4, import_yaml2, import_proof_frame, DEFAULT_TIMEOUT, ASSERTION_LOOKUP_MS, FLOW_TIMEOUT_SCALE, scaledTimeout, MAESTRO_SELECTOR_KEYS, SELECTOR_FILTER_KEYS, UNSUPPORTED_SELECTOR_KEYS, MAESTRO_PERMISSION_KINDS, MAESTRO_PERMISSION_STATUS, SootSimBridgeFlowRunner;
37551
37869
  var init_bridge_flow_runner = __esm({
37552
37870
  "cli/bridge-flow-runner.ts"() {
37553
37871
  "use strict";
37554
37872
  fs20 = __toESM(require("fs"), 1);
37555
37873
  path20 = __toESM(require("path"), 1);
37556
37874
  import_devices4 = require("peach-engine/settings/devices");
37557
- import_yaml = __toESM(require("yaml"), 1);
37875
+ import_yaml2 = __toESM(require("yaml"), 1);
37558
37876
  import_proof_frame = __toESM(require_proof_frame(), 1);
37559
37877
  init_flow_timeout_scale();
37560
37878
  init_frame_compose();
@@ -39284,7 +39602,10 @@ var init_bridge_flow_runner = __esm({
39284
39602
  }
39285
39603
  }
39286
39604
  try {
39287
- const hasExplicitWait = !!(step.extendedWaitUntil || step.waitFor || step.scrollUntilVisible || step.launchApp || step.runFlow || // retry reruns its body on failure, so its wall time is the body's
39605
+ const hasBoundedWait = !!// taps combine bounded lookup, settling and delivery. a wall-clock
39606
+ // watchdog can finish the step while that action is still running.
39607
+ // let these operations finish before starting the next command.
39608
+ (step.tapOn || step.doubleTapOn || step.longPressOn || step.extendedWaitUntil || step.waitFor || step.scrollUntilVisible || step.launchApp || step.runFlow || // retry reruns its body on failure, so its wall time is the body's
39288
39609
  // times the retry count — the 10s no-progress watchdog is the wrong
39289
39610
  // budget and would report "bridge probably hung" for a slow retry.
39290
39611
  step.retry || // runScript http calls are synchronous with a 5-minute upstream
@@ -39300,7 +39621,7 @@ var init_bridge_flow_runner = __esm({
39300
39621
  const STEP_WATCHDOG_MS = 1e4;
39301
39622
  const body = this.runStepInner(step);
39302
39623
  let screenshotPath;
39303
- if (hasExplicitWait) {
39624
+ if (hasBoundedWait) {
39304
39625
  const result = await body;
39305
39626
  if (typeof result === "string") screenshotPath = result;
39306
39627
  } else {