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;
@@ -3949,39 +3949,82 @@ function detectFramework(deps) {
3949
3949
  return "unknown";
3950
3950
  }
3951
3951
  function detectProject(dir) {
3952
- const pkgPath = (0, import_path2.join)(dir, "package.json");
3953
- if (!(0, import_fs2.existsSync)(pkgPath)) return null;
3954
- let pkg;
3955
- try {
3956
- pkg = JSON.parse((0, import_fs2.readFileSync)(pkgPath, "utf8"));
3957
- } catch {
3958
- return null;
3959
- }
3952
+ const pkgPath = (0, import_node_path16.join)(dir, "package.json");
3953
+ if (!(0, import_node_fs15.existsSync)(pkgPath)) return null;
3954
+ const pkg = readProjectManifest(dir);
3955
+ if (!pkg) return null;
3960
3956
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
3957
+ const devCommand = metadataValue(
3958
+ metadataValue(readProjectJson(pkgPath), "scripts"),
3959
+ "dev"
3960
+ );
3961
3961
  const framework = detectFramework(deps);
3962
3962
  if (framework === "unknown") return null;
3963
3963
  return {
3964
3964
  dir,
3965
- name: pkg.name || (0, import_path2.basename)(dir),
3965
+ name: pkg.name || (0, import_node_path16.basename)(dir),
3966
3966
  framework,
3967
3967
  // a config file is a config file whatever module system it declares. real
3968
3968
  // apps write .cjs as often as .js, and missing one reads as "this project
3969
3969
  // has no bundler config" and sends the user to create a second one.
3970
3970
  hasViteConfig: CONFIG_EXTENSIONS.some(
3971
- (ext) => (0, import_fs2.existsSync)((0, import_path2.join)(dir, `vite.config.${ext}`))
3971
+ (ext) => (0, import_node_fs15.existsSync)((0, import_node_path16.join)(dir, `vite.config.${ext}`))
3972
3972
  ),
3973
3973
  hasMetroConfig: CONFIG_EXTENSIONS.some(
3974
- (ext) => (0, import_fs2.existsSync)((0, import_path2.join)(dir, `metro.config.${ext}`))
3974
+ (ext) => (0, import_node_fs15.existsSync)((0, import_node_path16.join)(dir, `metro.config.${ext}`))
3975
3975
  ),
3976
- devCommand: pkg.scripts?.dev || null
3976
+ devCommand: typeof devCommand === "string" ? devCommand : null
3977
+ };
3978
+ }
3979
+ function readProjectMetadata(path12) {
3980
+ try {
3981
+ const info = (0, import_node_fs15.lstatSync)(path12);
3982
+ if (!info.isFile() || info.size > 4 * 1024 * 1024) return null;
3983
+ return (0, import_node_fs15.readFileSync)(path12, "utf8");
3984
+ } catch {
3985
+ return null;
3986
+ }
3987
+ }
3988
+ function metadataValue(value, key) {
3989
+ if (!value || typeof value !== "object") return void 0;
3990
+ return Object.getOwnPropertyDescriptor(value, key)?.value;
3991
+ }
3992
+ function readProjectJson(path12) {
3993
+ const text = readProjectMetadata(path12);
3994
+ if (text === null) return null;
3995
+ try {
3996
+ const value = JSON.parse(text);
3997
+ return value;
3998
+ } catch {
3999
+ return null;
4000
+ }
4001
+ }
4002
+ function readProjectManifest(dir) {
4003
+ const parsed = readProjectJson((0, import_node_path16.join)(dir, "package.json"));
4004
+ if (!parsed || typeof parsed !== "object") return null;
4005
+ const record = (value) => {
4006
+ if (!value || typeof value !== "object") return {};
4007
+ return Object.fromEntries(
4008
+ Object.entries(value).filter(
4009
+ (entry) => typeof entry[1] === "string" && /^(?:@[a-z0-9._-]+\/)?[a-z0-9._-]+$/i.test(entry[0]) && entry[0] !== "." && entry[0] !== ".."
4010
+ )
4011
+ );
4012
+ };
4013
+ const name2 = metadataValue(parsed, "name");
4014
+ return {
4015
+ ...typeof name2 === "string" ? { name: name2 } : {},
4016
+ dependencies: record(metadataValue(parsed, "dependencies")),
4017
+ devDependencies: record(metadataValue(parsed, "devDependencies"))
3977
4018
  };
3978
4019
  }
3979
- var import_fs2, import_path2, CONFIG_EXTENSIONS;
4020
+ var import_node_fs15, import_node_path16, import_json5, import_yaml, CONFIG_EXTENSIONS;
3980
4021
  var init_detect = __esm({
3981
4022
  "cli/commands/detect.ts"() {
3982
4023
  "use strict";
3983
- import_fs2 = require("fs");
3984
- import_path2 = require("path");
4024
+ import_node_fs15 = require("node:fs");
4025
+ import_node_path16 = require("node:path");
4026
+ import_json5 = __toESM(require("json5"), 1);
4027
+ import_yaml = require("yaml");
3985
4028
  CONFIG_EXTENSIONS = ["ts", "js", "cjs", "mjs", "mts", "cts"];
3986
4029
  }
3987
4030
  });
@@ -4016,21 +4059,21 @@ function resolveCloudOrigin(value) {
4016
4059
  return normalizeCloudOrigin(source);
4017
4060
  }
4018
4061
  function readImmutableBundleSource(bundlePath) {
4019
- const filepath = (0, import_node_path16.resolve)(bundlePath);
4020
- if ((0, import_node_path16.extname)(filepath) !== ".js") {
4062
+ const filepath = (0, import_node_path17.resolve)(bundlePath);
4063
+ if ((0, import_node_path17.extname)(filepath) !== ".js") {
4021
4064
  throw new Error(`${REMOTE_COMMAND} requires one local Metro .js bundle`);
4022
4065
  }
4023
- const descriptor = (0, import_node_fs15.openSync)(filepath, "r");
4066
+ const descriptor = (0, import_node_fs16.openSync)(filepath, "r");
4024
4067
  try {
4025
- const before = (0, import_node_fs15.fstatSync)(descriptor, { bigint: true });
4068
+ const before = (0, import_node_fs16.fstatSync)(descriptor, { bigint: true });
4026
4069
  if (!before.isFile()) {
4027
4070
  throw new Error(`${REMOTE_COMMAND} bundle must be a regular local file`);
4028
4071
  }
4029
4072
  if (before.size <= 0n) {
4030
4073
  throw new Error(`${REMOTE_COMMAND} bundle is empty`);
4031
4074
  }
4032
- const bytes = (0, import_node_fs15.readFileSync)(descriptor);
4033
- const after = (0, import_node_fs15.fstatSync)(descriptor, { bigint: true });
4075
+ const bytes = (0, import_node_fs16.readFileSync)(descriptor);
4076
+ const after = (0, import_node_fs16.fstatSync)(descriptor, { bigint: true });
4034
4077
  if (before.dev !== after.dev || before.ino !== after.ino || before.size !== after.size || before.mtimeNs !== after.mtimeNs || bytes.length !== Number(before.size)) {
4035
4078
  throw new Error(`${REMOTE_COMMAND} bundle changed while it was being read`);
4036
4079
  }
@@ -4045,7 +4088,7 @@ function readImmutableBundleSource(bundlePath) {
4045
4088
  }
4046
4089
  return source;
4047
4090
  } finally {
4048
- (0, import_node_fs15.closeSync)(descriptor);
4091
+ (0, import_node_fs16.closeSync)(descriptor);
4049
4092
  }
4050
4093
  }
4051
4094
  async function fetchBundleSource(bundleUrl) {
@@ -4092,15 +4135,15 @@ async function loadBundleSource(bundleInput) {
4092
4135
  return readImmutableBundleSource(bundleInput);
4093
4136
  }
4094
4137
  function listMetroAssetDest(assetsPath) {
4095
- const directory = (0, import_node_path16.resolve)(assetsPath);
4096
- if (!(0, import_node_fs15.existsSync)(directory)) return { directory, files: [], truncated: false };
4097
- const skipNested = (0, import_node_fs15.existsSync)((0, import_node_path16.join)(directory, "package.json"));
4138
+ const directory = (0, import_node_path17.resolve)(assetsPath);
4139
+ if (!(0, import_node_fs16.existsSync)(directory)) return { directory, files: [], truncated: false };
4140
+ const skipNested = (0, import_node_fs16.existsSync)((0, import_node_path17.join)(directory, "package.json"));
4098
4141
  const files = [];
4099
4142
  let truncated = false;
4100
4143
  const walk = (dir, prefix) => {
4101
4144
  let entries;
4102
4145
  try {
4103
- entries = (0, import_node_fs15.readdirSync)(dir, { withFileTypes: true });
4146
+ entries = (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true });
4104
4147
  } catch {
4105
4148
  return;
4106
4149
  }
@@ -4112,7 +4155,7 @@ function listMetroAssetDest(assetsPath) {
4112
4155
  if (entry.isDirectory()) {
4113
4156
  if (entry.name === ".git") continue;
4114
4157
  if (skipNested && PROJECT_ONLY_DIRECTORIES.has(entry.name)) continue;
4115
- walk((0, import_node_path16.join)(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name);
4158
+ walk((0, import_node_path17.join)(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name);
4116
4159
  } else if (entry.isFile()) {
4117
4160
  files.push(prefix ? `${prefix}/${entry.name}` : entry.name);
4118
4161
  }
@@ -4147,7 +4190,7 @@ function distinctByContent(directory, options) {
4147
4190
  for (const relative2 of options) {
4148
4191
  let bytes;
4149
4192
  try {
4150
- bytes = (0, import_node_fs15.readFileSync)((0, import_node_path16.join)(directory, relative2));
4193
+ bytes = (0, import_node_fs16.readFileSync)((0, import_node_path17.join)(directory, relative2));
4151
4194
  } catch {
4152
4195
  continue;
4153
4196
  }
@@ -4179,7 +4222,7 @@ function placeMetroDescriptor(listing, descriptor) {
4179
4222
  let bytes;
4180
4223
  try {
4181
4224
  bytes = combination.map(
4182
- (relative2) => (0, import_node_fs15.readFileSync)((0, import_node_path16.join)(listing.directory, relative2))
4225
+ (relative2) => (0, import_node_fs16.readFileSync)((0, import_node_path17.join)(listing.directory, relative2))
4183
4226
  );
4184
4227
  } catch {
4185
4228
  continue;
@@ -4205,26 +4248,26 @@ function placeMetroDescriptor(listing, descriptor) {
4205
4248
  }
4206
4249
  function unverifiedFileKey(dest) {
4207
4250
  return dest.placements.filter((placement) => !placement.verified).flatMap(
4208
- (placement) => [...placement.files.values()].map((relative2) => (0, import_node_path16.join)(dest.directory, relative2))
4251
+ (placement) => [...placement.files.values()].map((relative2) => (0, import_node_path17.join)(dest.directory, relative2))
4209
4252
  ).sort().join("\n");
4210
4253
  }
4211
4254
  function searchMetroAssetDest(bundlePath, descriptors) {
4212
- const bundleDirectory = (0, import_node_path16.dirname)((0, import_node_path16.resolve)(bundlePath));
4255
+ const bundleDirectory = (0, import_node_path17.dirname)((0, import_node_path17.resolve)(bundlePath));
4213
4256
  const candidates = [
4214
- (0, import_node_path16.join)(bundleDirectory, "assets"),
4257
+ (0, import_node_path17.join)(bundleDirectory, "assets"),
4215
4258
  bundleDirectory,
4216
- (0, import_node_path16.resolve)(bundleDirectory, "..", "assets")
4259
+ (0, import_node_path17.resolve)(bundleDirectory, "..", "assets")
4217
4260
  ];
4218
4261
  const cwd = process.cwd();
4219
4262
  let projectDirectory = null;
4220
4263
  for (const start of [bundleDirectory, cwd]) {
4221
- let directory = (0, import_node_path16.resolve)(start);
4264
+ let directory = (0, import_node_path17.resolve)(start);
4222
4265
  while (true) {
4223
4266
  if (detectProject(directory)?.hasMetroConfig) {
4224
4267
  projectDirectory = directory;
4225
4268
  break;
4226
4269
  }
4227
- const parent = (0, import_node_path16.dirname)(directory);
4270
+ const parent = (0, import_node_path17.dirname)(directory);
4228
4271
  if (parent === directory) break;
4229
4272
  directory = parent;
4230
4273
  }
@@ -4232,11 +4275,11 @@ function searchMetroAssetDest(bundlePath, descriptors) {
4232
4275
  }
4233
4276
  if (projectDirectory) {
4234
4277
  candidates.push(
4235
- (0, import_node_path16.join)(projectDirectory, "assets"),
4236
- (0, import_node_path16.join)(projectDirectory, "dist"),
4237
- (0, import_node_path16.join)(projectDirectory, "dist", "assets"),
4238
- (0, import_node_path16.join)(projectDirectory, "build"),
4239
- (0, import_node_path16.join)(projectDirectory, "build", "assets")
4278
+ (0, import_node_path17.join)(projectDirectory, "assets"),
4279
+ (0, import_node_path17.join)(projectDirectory, "dist"),
4280
+ (0, import_node_path17.join)(projectDirectory, "dist", "assets"),
4281
+ (0, import_node_path17.join)(projectDirectory, "build"),
4282
+ (0, import_node_path17.join)(projectDirectory, "build", "assets")
4240
4283
  );
4241
4284
  }
4242
4285
  const searched = [];
@@ -4244,7 +4287,7 @@ function searchMetroAssetDest(bundlePath, descriptors) {
4244
4287
  const stale = [];
4245
4288
  let truncated = false;
4246
4289
  for (const candidate of candidates) {
4247
- const directory = (0, import_node_path16.resolve)(candidate);
4290
+ const directory = (0, import_node_path17.resolve)(candidate);
4248
4291
  if (searched.includes(directory)) continue;
4249
4292
  searched.push(directory);
4250
4293
  const listing = listMetroAssetDest(directory);
@@ -4350,7 +4393,7 @@ async function embedBundleAssets(bundlePath, command, assetPolicy) {
4350
4393
  );
4351
4394
  }
4352
4395
  const relative2 = placement?.files.get(variant.scale);
4353
- if (relative2 && dest) return (0, import_node_fs15.readFileSync)((0, import_node_path16.join)(dest.directory, relative2));
4396
+ if (relative2 && dest) return (0, import_node_fs16.readFileSync)((0, import_node_path17.join)(dest.directory, relative2));
4354
4397
  if (placement && placement.files.size > 0) return null;
4355
4398
  if (placement && placement.ambiguous.length > 0 && dest) {
4356
4399
  throw new Error(
@@ -4379,7 +4422,7 @@ async function embedBundleAssets(bundlePath, command, assetPolicy) {
4379
4422
  );
4380
4423
  const classic = metroIosAssetDestRelatives(variant.descriptor.httpServerLocation, filename)[0] ?? filename;
4381
4424
  throw new Error(
4382
- `${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\`.`
4425
+ `${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\`.`
4383
4426
  );
4384
4427
  });
4385
4428
  return {
@@ -4525,13 +4568,13 @@ async function createCloudBox(options) {
4525
4568
  warnings: artifact.warnings
4526
4569
  };
4527
4570
  }
4528
- 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;
4571
+ 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;
4529
4572
  var init_cloud_client = __esm({
4530
4573
  "cli/cloud-client.ts"() {
4531
4574
  "use strict";
4532
4575
  import_node_crypto6 = require("node:crypto");
4533
- import_node_fs15 = require("node:fs");
4534
- import_node_path16 = require("node:path");
4576
+ import_node_fs16 = require("node:fs");
4577
+ import_node_path17 = require("node:path");
4535
4578
  init_metroAssetArtifact();
4536
4579
  init_metroCloudArtifact();
4537
4580
  init_metro_fingerprint_registry_client();
@@ -4637,9 +4680,9 @@ __export(bridge_host_exports, {
4637
4680
  });
4638
4681
  module.exports = __toCommonJS(bridge_host_exports);
4639
4682
  var import_child_process3 = require("child_process");
4640
- var import_fs3 = __toESM(require("fs"), 1);
4683
+ var import_fs2 = __toESM(require("fs"), 1);
4641
4684
  var import_http4 = require("http");
4642
- var import_path3 = __toESM(require("path"), 1);
4685
+ var import_path2 = __toESM(require("path"), 1);
4643
4686
  var import_ws = require("ws");
4644
4687
 
4645
4688
  // scripts/dev-server-scanner.ts
@@ -9513,7 +9556,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
9513
9556
  async startAsync(options) {
9514
9557
  if (this.httpServer || this.wss) return this.effectivePort;
9515
9558
  this.refreshActiveRuntime();
9516
- this.bootstrapping = !this.activeRuntimeDirPath || !import_fs3.default.existsSync(import_path3.default.join(this.activeRuntimeDirPath, "index.html"));
9559
+ this.bootstrapping = !this.activeRuntimeDirPath || !import_fs2.default.existsSync(import_path2.default.join(this.activeRuntimeDirPath, "index.html"));
9517
9560
  for (let attempt = 0; attempt < this.portFallbackCount; attempt++) {
9518
9561
  const candidate = this.preferredPort + attempt;
9519
9562
  try {
@@ -10185,10 +10228,10 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
10185
10228
  return;
10186
10229
  }
10187
10230
  const root = cameraFixturesDir();
10188
- const filePath = import_path3.default.join(root, name2);
10231
+ const filePath = import_path2.default.join(root, name2);
10189
10232
  let stats;
10190
10233
  try {
10191
- stats = import_fs3.default.lstatSync(filePath);
10234
+ stats = import_fs2.default.lstatSync(filePath);
10192
10235
  } catch {
10193
10236
  res.writeHead(404, { ...cors, "Content-Type": "text/plain; charset=utf-8" });
10194
10237
  res.end("not found");
@@ -10199,7 +10242,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
10199
10242
  res.end("forbidden");
10200
10243
  return;
10201
10244
  }
10202
- const contentType = HTTP_MIME_TYPES[import_path3.default.extname(filePath).toLowerCase()] || "application/octet-stream";
10245
+ const contentType = HTTP_MIME_TYPES[import_path2.default.extname(filePath).toLowerCase()] || "application/octet-stream";
10203
10246
  sendFileWithRanges(req, res, filePath, stats.size, {
10204
10247
  ...cors,
10205
10248
  "Content-Type": contentType
@@ -10576,34 +10619,34 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
10576
10619
  return;
10577
10620
  }
10578
10621
  }
10579
- const resolved = import_path3.default.resolve(baseDir, "." + rel);
10580
- const baseWithSep = baseDir.endsWith(import_path3.default.sep) ? baseDir : baseDir + import_path3.default.sep;
10622
+ const resolved = import_path2.default.resolve(baseDir, "." + rel);
10623
+ const baseWithSep = baseDir.endsWith(import_path2.default.sep) ? baseDir : baseDir + import_path2.default.sep;
10581
10624
  if (!resolved.startsWith(baseWithSep) && resolved !== baseDir) {
10582
10625
  res.writeHead(403);
10583
10626
  res.end("forbidden");
10584
10627
  return;
10585
10628
  }
10586
- import_fs3.default.realpath(resolved, (realErr, realResolved) => {
10629
+ import_fs2.default.realpath(resolved, (realErr, realResolved) => {
10587
10630
  const servePath = realErr ? resolved : realResolved;
10588
- const servePathWithSep = servePath.endsWith(import_path3.default.sep) ? servePath : servePath + import_path3.default.sep;
10631
+ const servePathWithSep = servePath.endsWith(import_path2.default.sep) ? servePath : servePath + import_path2.default.sep;
10589
10632
  if (!realErr) {
10590
10633
  const realBaseWithSep = (() => {
10591
10634
  try {
10592
- const rb = import_fs3.default.realpathSync(baseDir);
10593
- return rb.endsWith(import_path3.default.sep) ? rb : rb + import_path3.default.sep;
10635
+ const rb = import_fs2.default.realpathSync(baseDir);
10636
+ return rb.endsWith(import_path2.default.sep) ? rb : rb + import_path2.default.sep;
10594
10637
  } catch {
10595
10638
  return baseWithSep;
10596
10639
  }
10597
10640
  })();
10598
- if (!servePathWithSep.startsWith(realBaseWithSep) && servePath + import_path3.default.sep !== realBaseWithSep) {
10641
+ if (!servePathWithSep.startsWith(realBaseWithSep) && servePath + import_path2.default.sep !== realBaseWithSep) {
10599
10642
  res.writeHead(403);
10600
10643
  res.end("forbidden");
10601
10644
  return;
10602
10645
  }
10603
10646
  }
10604
- import_fs3.default.stat(servePath, (err, stats) => {
10647
+ import_fs2.default.stat(servePath, (err, stats) => {
10605
10648
  if (err || !stats?.isFile()) {
10606
- const ext2 = import_path3.default.extname(rel).toLowerCase();
10649
+ const ext2 = import_path2.default.extname(rel).toLowerCase();
10607
10650
  if (ext2 && ext2 !== ".html") {
10608
10651
  res.writeHead(404);
10609
10652
  res.end("not found");
@@ -10614,8 +10657,8 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
10614
10657
  res.end("not found");
10615
10658
  return;
10616
10659
  }
10617
- const indexPath = import_path3.default.join(baseDir, "index.html");
10618
- import_fs3.default.readFile(indexPath, (err2, data) => {
10660
+ const indexPath = import_path2.default.join(baseDir, "index.html");
10661
+ import_fs2.default.readFile(indexPath, (err2, data) => {
10619
10662
  if (err2) {
10620
10663
  res.writeHead(404);
10621
10664
  res.end("not found");
@@ -10635,7 +10678,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
10635
10678
  });
10636
10679
  return;
10637
10680
  }
10638
- const ext = import_path3.default.extname(servePath).toLowerCase();
10681
+ const ext = import_path2.default.extname(servePath).toLowerCase();
10639
10682
  const contentType = HTTP_MIME_TYPES[ext] || "application/octet-stream";
10640
10683
  res.writeHead(200, {
10641
10684
  "Content-Type": contentType,
@@ -10646,7 +10689,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
10646
10689
  return;
10647
10690
  }
10648
10691
  if (ext === ".html") {
10649
- import_fs3.default.readFile(servePath, (readErr, data) => {
10692
+ import_fs2.default.readFile(servePath, (readErr, data) => {
10650
10693
  if (readErr) {
10651
10694
  try {
10652
10695
  res.end();
@@ -10660,7 +10703,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
10660
10703
  });
10661
10704
  return;
10662
10705
  }
10663
- const stream = import_fs3.default.createReadStream(servePath);
10706
+ const stream = import_fs2.default.createReadStream(servePath);
10664
10707
  stream.pipe(res);
10665
10708
  stream.on("error", () => {
10666
10709
  try {
@@ -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;
@@ -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 __defProp = Object.defineProperty;
@@ -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
 
3
3
  // src/host/fetch-proxy-overrides.ts
4
4
  var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
@@ -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;
@@ -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 __defProp = Object.defineProperty;
@@ -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;
@@ -433,6 +433,10 @@ function readCloudSession(environment = process.env) {
433
433
  return encoded?.trim() ? parseCloudSession(encoded) : null;
434
434
  }
435
435
 
436
+ // cli/commands/detect.ts
437
+ var import_json5 = __toESM(require("json5"), 1);
438
+ var import_yaml = require("yaml");
439
+
436
440
  // cli/cloud-client.ts
437
441
  var DEFAULT_RNX_CLOUD_ORIGIN = rnxPublicBrand.origin;
438
442
  function failureSentence(text) {
@@ -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 __defProp = Object.defineProperty;
@@ -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;
@@ -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;
package/dist-lib/menu.cjs CHANGED
@@ -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 __defProp = Object.defineProperty;
@@ -290,6 +290,16 @@ function debugMenu(state) {
290
290
  return {
291
291
  label: "Debug",
292
292
  items: [
293
+ {
294
+ label: "Slow Animations",
295
+ type: "checkbox",
296
+ checked: state.slowAnimations,
297
+ accelerator: "Shift+Alt+S",
298
+ action: "toggle-slow-animations",
299
+ browserAccelerator: true,
300
+ showInShortcutDocs: true
301
+ },
302
+ { type: "separator" },
293
303
  // both toggles are stateful in the browser, where the open state lives
294
304
  // in the same document. electron's menu process cannot see it, so it
295
305
  // keeps the plain (stateless) items rather than a permanently
package/dist-lib/menu.mjs CHANGED
@@ -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
 
3
3
  // src/public-brand.ts
4
4
  var name = "Peach";
@@ -249,6 +249,16 @@ function debugMenu(state) {
249
249
  return {
250
250
  label: "Debug",
251
251
  items: [
252
+ {
253
+ label: "Slow Animations",
254
+ type: "checkbox",
255
+ checked: state.slowAnimations,
256
+ accelerator: "Shift+Alt+S",
257
+ action: "toggle-slow-animations",
258
+ browserAccelerator: true,
259
+ showInShortcutDocs: true
260
+ },
261
+ { type: "separator" },
252
262
  // both toggles are stateful in the browser, where the open state lives
253
263
  // in the same document. electron's menu process cannot see it, so it
254
264
  // keeps the plain (stateless) items rather than a permanently
@@ -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 __defProp = Object.defineProperty;
@@ -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
 
3
3
  // src/is-record.ts
4
4
  function isRecord(value) {
@@ -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 __defProp = Object.defineProperty;
@@ -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
 
3
3
  // src/metro-production-bundle.ts
4
4
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
@@ -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;
@@ -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 __defProp = Object.defineProperty;
@@ -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
 
3
3
  // src/native-app-identity.ts
4
4
  var NATIVE_APP_IDENTITY_PREFIX = "globalThis.__sootsimNativeAppIdentity=";
@@ -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;
@@ -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 __defProp = Object.defineProperty;
@@ -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 __defProp = Object.defineProperty;
@@ -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
 
3
3
  // src/react-native-host-modules.ts
4
4
  var REACT_NATIVE_PASSTHROUGH_SPECIFIERS = [
@@ -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 __defProp = Object.defineProperty;
@@ -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;
package/dist-lib/sdk.cjs CHANGED
@@ -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 __defProp = Object.defineProperty;
@@ -39,6 +39,7 @@ __export(sdk_exports, {
39
39
  clearConsole: () => clearConsole,
40
40
  clearLogs: () => clearLogs,
41
41
  clearRequests: () => clearRequests,
42
+ consoleEntriesEval: () => consoleEntriesEval,
42
43
  detectOpenNativeUI: () => detectOpenNativeUI,
43
44
  filterLogEntries: () => filterLogEntries,
44
45
  formatLayoutElements: () => formatLayoutElements,
@@ -2514,6 +2515,7 @@ var SimClient = class {
2514
2515
  clearConsole,
2515
2516
  clearLogs,
2516
2517
  clearRequests,
2518
+ consoleEntriesEval,
2517
2519
  detectOpenNativeUI,
2518
2520
  filterLogEntries,
2519
2521
  formatLayoutElements,