peachsim 0.1.662 → 0.1.664

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 (78) hide show
  1. package/cli/commands/control.ts +9 -17
  2. package/cli/commands/inspect/core.ts +44 -23
  3. package/cli/commands/inspect/settling.ts +54 -1
  4. package/cli/commands/inspect/wait-ready.ts +40 -70
  5. package/dist-lib/agent-daemon-client.cjs +1 -1
  6. package/dist-lib/agent-events.cjs +1 -1
  7. package/dist-lib/agent-identity.cjs +1 -1
  8. package/dist-lib/agent-sessions.cjs +1 -1
  9. package/dist-lib/attached-projects.cjs +1 -1
  10. package/dist-lib/auth/shared-session.cjs +1 -1
  11. package/dist-lib/backend-origin.cjs +1 -1
  12. package/dist-lib/beta.cjs +1 -1
  13. package/dist-lib/beta.mjs +1 -1
  14. package/dist-lib/bridge-constants.cjs +1 -1
  15. package/dist-lib/bridge-contract-input.cjs +1 -1
  16. package/dist-lib/bridge-contract-input.mjs +1 -1
  17. package/dist-lib/bridge-contract.cjs +6 -1
  18. package/dist-lib/bridge-contract.mjs +5 -1
  19. package/dist-lib/capture-contract.cjs +1 -1
  20. package/dist-lib/capture-contract.mjs +1 -1
  21. package/dist-lib/cli-constants.cjs +1 -1
  22. package/dist-lib/cloud-contract.cjs +1 -1
  23. package/dist-lib/cloud-contract.mjs +1 -1
  24. package/dist-lib/cloud-test-args.cjs +1 -1
  25. package/dist-lib/cloud-test-args.mjs +1 -1
  26. package/dist-lib/cloud.cjs +1 -1
  27. package/dist-lib/cloud.mjs +1 -1
  28. package/dist-lib/config.cjs +1 -1
  29. package/dist-lib/detox/index.cjs +1 -1
  30. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  31. package/dist-lib/home-paths.cjs +1 -1
  32. package/dist-lib/host/bridge-host.cjs +1 -1
  33. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  34. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  35. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  36. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  37. package/dist-lib/host/websocket-proxy.cjs +1 -1
  38. package/dist-lib/index.cjs +16 -17
  39. package/dist-lib/jump-to-source-babel.cjs +1 -1
  40. package/dist-lib/jump-to-source-native.cjs +1 -1
  41. package/dist-lib/kotlin-host.cjs +13 -7
  42. package/dist-lib/menu.cjs +1 -1
  43. package/dist-lib/menu.mjs +1 -1
  44. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  45. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  46. package/dist-lib/metro-production-bundle.cjs +1 -1
  47. package/dist-lib/metro-production-bundle.mjs +1 -1
  48. package/dist-lib/metro.cjs +1 -1
  49. package/dist-lib/native-app-identity.cjs +1 -1
  50. package/dist-lib/native-app-identity.mjs +1 -1
  51. package/dist-lib/plist.cjs +1 -1
  52. package/dist-lib/plist.mjs +1 -1
  53. package/dist-lib/profiles.cjs +1 -1
  54. package/dist-lib/public-brand.cjs +1 -1
  55. package/dist-lib/react-native-host-modules.cjs +1 -1
  56. package/dist-lib/react-native-host-modules.mjs +1 -1
  57. package/dist-lib/render-mode.cjs +1 -1
  58. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  59. package/dist-lib/sdk.cjs +57 -17
  60. package/dist-lib/sdk.mjs +54 -17
  61. package/dist-lib/skills.cjs +38 -27
  62. package/dist-lib/swift-compile.cjs +1 -1
  63. package/dist-lib/swift-compile.mjs +1 -1
  64. package/dist-lib/swift-package.cjs +1 -1
  65. package/dist-lib/swift-package.mjs +1 -1
  66. package/dist-lib/swift-submit.cjs +1 -1
  67. package/dist-lib/swift-submit.mjs +1 -1
  68. package/dist-lib/swift.cjs +1 -1
  69. package/dist-lib/vite-swift.cjs +1 -1
  70. package/dist-lib/vite.cjs +1 -1
  71. package/kotlin/AppSources/dev/peach/app/PeachApp.kt +8 -2
  72. package/kotlin/fixtures/kotlin-app-variants/Widgets.kt +56 -0
  73. package/package.json +1 -1
  74. package/src/bridge-contract.ts +15 -0
  75. package/src/generated/android-framework-themes.json +341 -0
  76. package/src/kotlin-app.ts +47 -26
  77. package/src/kotlin-host.ts +14 -7
  78. package/src/sdk.ts +2 -1
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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;
@@ -1924,33 +1924,34 @@ function waitReadyReason(status) {
1924
1924
  return !status.externalError && status.suppressedEntryError ? `${base} (suppressed entry error: ${status.suppressedEntryError})` : base;
1925
1925
  }
1926
1926
  async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
1927
+ const result = await sendReadyWait(bridge, timeoutMs, timeoutMs + 1e3, options.simId);
1928
+ const status = waitReadyStatus(result, result.matched && !result.probe?.externalError);
1929
+ if (!status.ready && options.onProgress) options.onProgress(status);
1930
+ return status;
1931
+ }
1932
+ async function sendReadyWait(bridge, timeoutMs, sendTimeoutMs, simId) {
1927
1933
  const start = Date.now();
1928
- let result;
1929
1934
  try {
1930
- result = await bridge.send(
1935
+ return await bridge.send(
1931
1936
  {
1932
1937
  type: "waitFor",
1933
- ...options.simId ? { simId: options.simId } : {},
1938
+ ...simId ? { simId } : {},
1934
1939
  waitForOptions: { condition: { type: "ready" }, timeoutMs }
1935
1940
  },
1936
- { timeoutMs: timeoutMs + 1e3 }
1941
+ { timeoutMs: sendTimeoutMs }
1937
1942
  );
1938
1943
  } catch (error) {
1939
1944
  const bridgeError = error instanceof Error ? error.message : String(error);
1940
1945
  if (bridgeError.startsWith("multiple sims are connected:") || bridgeError.startsWith("saved sim ")) {
1941
1946
  throw error;
1942
1947
  }
1943
- result = {
1944
- matched: false,
1945
- elapsedMs: Date.now() - start,
1946
- polls: 0,
1947
- error: bridgeError
1948
- };
1948
+ return { matched: false, elapsedMs: Date.now() - start, polls: 0, error: bridgeError };
1949
1949
  }
1950
+ }
1951
+ function waitReadyStatus(result, ready) {
1950
1952
  const probe = result.probe;
1951
- const externalError = probe?.externalError ?? "";
1952
- const status = {
1953
- ready: result.matched && !externalError,
1953
+ return {
1954
+ ready,
1954
1955
  elapsedMs: result.elapsedMs,
1955
1956
  nodes: probe?.nodes ?? 0,
1956
1957
  targets: probe?.targets ?? 0,
@@ -1961,13 +1962,11 @@ async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
1961
1962
  loadingText: probe?.loadingText ?? "",
1962
1963
  externalReady: probe?.externalReady ?? null,
1963
1964
  externalStatus: probe?.externalStatus ?? "",
1964
- externalError,
1965
+ externalError: probe?.externalError ?? "",
1965
1966
  suppressedEntryError: probe?.suppressedEntryError ?? "",
1966
1967
  errors: probe?.errors ?? 0,
1967
1968
  bridgeError: result.error ?? ""
1968
1969
  };
1969
- if (!status.ready && options.onProgress) options.onProgress(status);
1970
- return status;
1971
1970
  }
1972
1971
  function consoleEntriesEval(level, limit) {
1973
1972
  const getter = level === "error" ? "getErrors" : "getWarnings";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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;
@@ -375,6 +375,16 @@ function viewModelInitializer({ name, signature }) {
375
375
  )}) }`;
376
376
  }
377
377
  }
378
+ function windowTheme(window) {
379
+ const argb = (color) => `0x${color.toString(16).padStart(8, "0")}.toInt()`;
380
+ return [
381
+ " android.view.WindowTheme(",
382
+ ` ${window.edgeToEdgeEnforced}, ${argb(window.statusBarColor)}, ${argb(window.navigationBarColor)},`,
383
+ ` ${window.statusBarContrastEnforced}, ${window.navigationBarContrastEnforced},`,
384
+ ` ${window.lightStatusBar}, ${window.lightNavigationBar},`,
385
+ " ),"
386
+ ];
387
+ }
378
388
  async function kotlinAppArtifact(app, moduleRoot, origin) {
379
389
  const toolchain = readToolchain(moduleRoot);
380
390
  const kotlinString = (value) => JSON.stringify(value).replaceAll("$", "\\$");
@@ -390,12 +400,8 @@ async function kotlinAppArtifact(app, moduleRoot, origin) {
390
400
  " dev.peach.app.PeachAppSpec(",
391
401
  ` android.content.ComponentName(${kotlinString(app.packageName)}, ${kotlinString(app.launcher.name)}),`,
392
402
  ` android.content.ComponentName(${kotlinString(app.packageName)}, ${kotlinString(app.launcher.targetClass)}),`,
393
- " android.view.WindowTheme(",
394
- ` ${app.window.edgeToEdgeEnforced}, 0x${app.window.statusBarColor.toString(16).padStart(8, "0")}.toInt(),`,
395
- ` 0x${app.window.navigationBarColor.toString(16).padStart(8, "0")}.toInt(),`,
396
- ` ${app.window.statusBarContrastEnforced}, ${app.window.navigationBarContrastEnforced},`,
397
- ` ${app.window.lightStatusBar}, ${app.window.lightNavigationBar},`,
398
- " ),",
403
+ ...windowTheme(app.window.day),
404
+ ...windowTheme(app.window.night),
399
405
  ` { ${app.applicationClass ?? "android.app.Application"}() },`,
400
406
  ` { ${app.launcher.targetClass}() },`,
401
407
  ` ${app.handlesUiMode},`,
package/dist-lib/menu.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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;
package/dist-lib/menu.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/public-brand.ts
4
4
  var name = "Peach";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/plist.ts
4
4
  import plistModule from "@expo/plist";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (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;
@@ -62,6 +62,7 @@ __export(sdk_exports, {
62
62
  inspectLogs: () => inspectLogs,
63
63
  inspectMemory: () => inspectMemory,
64
64
  inspectNodeCount: () => inspectNodeCount,
65
+ inspectReadySnapshot: () => inspectReadySnapshot,
65
66
  inspectRequests: () => inspectRequests,
66
67
  inspectScreens: () => inspectScreens,
67
68
  inspectScrollStateAt: () => inspectScrollStateAt,
@@ -84,6 +85,7 @@ __export(sdk_exports, {
84
85
  rankInteractive: () => rankInteractive,
85
86
  readyProbeHasContent: () => readyProbeHasContent,
86
87
  readyProbeHasTargetContent: () => readyProbeHasTargetContent,
88
+ readyProbeIsReady: () => readyProbeIsReady,
87
89
  resolveFindMode: () => resolveFindMode,
88
90
  resolveMaxMsFlag: () => resolveMaxMsFlag,
89
91
  scoreInteractive: () => scoreInteractive,
@@ -99,6 +101,7 @@ __export(sdk_exports, {
99
101
  tapResolvedTarget: () => tapResolvedTarget,
100
102
  tapTargetFromPayload: () => tapTargetFromPayload,
101
103
  waitForSootsimIdle: () => waitForSootsimIdle,
104
+ waitReadyAndSettle: () => waitReadyAndSettle,
102
105
  waitReadyReason: () => waitReadyReason
103
106
  });
104
107
  module.exports = __toCommonJS(sdk_exports);
@@ -113,6 +116,9 @@ function readyProbeHasContent(probe) {
113
116
  function readyProbeHasTargetContent(probe) {
114
117
  return probe.liveFrameActive || probe.targets > 0;
115
118
  }
119
+ function readyProbeIsReady(probe) {
120
+ return (probe.flag === true ? readyProbeHasContent(probe) : readyProbeHasTargetContent(probe)) && probe.externalReady !== false && !probe.externalError && !probe.loadingText;
121
+ }
116
122
 
117
123
  // cli/commands/inspect/core.ts
118
124
  function resolveMaxMsFlag(args, fallbackMs) {
@@ -853,33 +859,38 @@ function waitReadyReason(status) {
853
859
  return !status.externalError && status.suppressedEntryError ? `${base} (suppressed entry error: ${status.suppressedEntryError})` : base;
854
860
  }
855
861
  async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
862
+ const result = await sendReadyWait(bridge, timeoutMs, timeoutMs + 1e3, options.simId);
863
+ const status = waitReadyStatus(result, result.matched && !result.probe?.externalError);
864
+ if (!status.ready && options.onProgress) options.onProgress(status);
865
+ return status;
866
+ }
867
+ async function inspectReadySnapshot(bridge, sendTimeoutMs, simId) {
868
+ const result = await sendReadyWait(bridge, 1, sendTimeoutMs, simId);
869
+ return waitReadyStatus(result, result.probe ? readyProbeIsReady(result.probe) : false);
870
+ }
871
+ async function sendReadyWait(bridge, timeoutMs, sendTimeoutMs, simId) {
856
872
  const start = Date.now();
857
- let result;
858
873
  try {
859
- result = await bridge.send(
874
+ return await bridge.send(
860
875
  {
861
876
  type: "waitFor",
862
- ...options.simId ? { simId: options.simId } : {},
877
+ ...simId ? { simId } : {},
863
878
  waitForOptions: { condition: { type: "ready" }, timeoutMs }
864
879
  },
865
- { timeoutMs: timeoutMs + 1e3 }
880
+ { timeoutMs: sendTimeoutMs }
866
881
  );
867
882
  } catch (error) {
868
883
  const bridgeError = error instanceof Error ? error.message : String(error);
869
884
  if (bridgeError.startsWith("multiple sims are connected:") || bridgeError.startsWith("saved sim ")) {
870
885
  throw error;
871
886
  }
872
- result = {
873
- matched: false,
874
- elapsedMs: Date.now() - start,
875
- polls: 0,
876
- error: bridgeError
877
- };
887
+ return { matched: false, elapsedMs: Date.now() - start, polls: 0, error: bridgeError };
878
888
  }
889
+ }
890
+ function waitReadyStatus(result, ready) {
879
891
  const probe = result.probe;
880
- const externalError = probe?.externalError ?? "";
881
- const status = {
882
- ready: result.matched && !externalError,
892
+ return {
893
+ ready,
883
894
  elapsedMs: result.elapsedMs,
884
895
  nodes: probe?.nodes ?? 0,
885
896
  targets: probe?.targets ?? 0,
@@ -890,13 +901,11 @@ async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
890
901
  loadingText: probe?.loadingText ?? "",
891
902
  externalReady: probe?.externalReady ?? null,
892
903
  externalStatus: probe?.externalStatus ?? "",
893
- externalError,
904
+ externalError: probe?.externalError ?? "",
894
905
  suppressedEntryError: probe?.suppressedEntryError ?? "",
895
906
  errors: probe?.errors ?? 0,
896
907
  bridgeError: result.error ?? ""
897
908
  };
898
- if (!status.ready && options.onProgress) options.onProgress(status);
899
- return status;
900
909
  }
901
910
  async function inspectWaitSelector(bridge, testId, timeoutMs = 5e3, opts = {}) {
902
911
  const gone = opts.gone === true;
@@ -1683,6 +1692,34 @@ async function waitForSootsimIdle({
1683
1692
  blockedBy: typeof blockedBy === "string" ? blockedBy : "unknown"
1684
1693
  };
1685
1694
  }
1695
+ async function waitReadyAndSettle(bridge, timeoutMs, options = {}) {
1696
+ const start = Date.now();
1697
+ const remaining = () => Math.max(0, start + timeoutMs - Date.now());
1698
+ const result = (status, idle2) => ({
1699
+ status,
1700
+ idle: idle2,
1701
+ elapsedMs: Date.now() - start
1702
+ });
1703
+ let idle = null;
1704
+ for (; ; ) {
1705
+ const ready = await inspectWaitReady(bridge, remaining(), options);
1706
+ if (!ready.ready) return result(ready, idle);
1707
+ idle = await waitForSootsimIdle({
1708
+ bridge,
1709
+ simId: options.simId,
1710
+ maxMs: Math.min(1e4, remaining()),
1711
+ pollMs: 32,
1712
+ stablePolls: 2
1713
+ });
1714
+ if (!idle.settled) return result(ready, idle);
1715
+ const settled = await inspectReadySnapshot(
1716
+ bridge,
1717
+ Math.max(1e3, remaining()),
1718
+ options.simId
1719
+ );
1720
+ if (settled.ready || remaining() === 0) return result(settled, idle);
1721
+ }
1722
+ }
1686
1723
 
1687
1724
  // cli/commands/inspect/actions.ts
1688
1725
  var DEFAULT_AGENT_TIMING = {
@@ -2582,6 +2619,7 @@ var SimClient = class {
2582
2619
  inspectLogs,
2583
2620
  inspectMemory,
2584
2621
  inspectNodeCount,
2622
+ inspectReadySnapshot,
2585
2623
  inspectRequests,
2586
2624
  inspectScreens,
2587
2625
  inspectScrollStateAt,
@@ -2604,6 +2642,7 @@ var SimClient = class {
2604
2642
  rankInteractive,
2605
2643
  readyProbeHasContent,
2606
2644
  readyProbeHasTargetContent,
2645
+ readyProbeIsReady,
2607
2646
  resolveFindMode,
2608
2647
  resolveMaxMsFlag,
2609
2648
  scoreInteractive,
@@ -2619,5 +2658,6 @@ var SimClient = class {
2619
2658
  tapResolvedTarget,
2620
2659
  tapTargetFromPayload,
2621
2660
  waitForSootsimIdle,
2661
+ waitReadyAndSettle,
2622
2662
  waitReadyReason
2623
2663
  });
package/dist-lib/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.662 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.664 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -13,6 +13,9 @@ function readyProbeHasContent(probe) {
13
13
  function readyProbeHasTargetContent(probe) {
14
14
  return probe.liveFrameActive || probe.targets > 0;
15
15
  }
16
+ function readyProbeIsReady(probe) {
17
+ return (probe.flag === true ? readyProbeHasContent(probe) : readyProbeHasTargetContent(probe)) && probe.externalReady !== false && !probe.externalError && !probe.loadingText;
18
+ }
16
19
 
17
20
  // cli/commands/inspect/core.ts
18
21
  function resolveMaxMsFlag(args, fallbackMs) {
@@ -753,33 +756,38 @@ function waitReadyReason(status) {
753
756
  return !status.externalError && status.suppressedEntryError ? `${base} (suppressed entry error: ${status.suppressedEntryError})` : base;
754
757
  }
755
758
  async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
759
+ const result = await sendReadyWait(bridge, timeoutMs, timeoutMs + 1e3, options.simId);
760
+ const status = waitReadyStatus(result, result.matched && !result.probe?.externalError);
761
+ if (!status.ready && options.onProgress) options.onProgress(status);
762
+ return status;
763
+ }
764
+ async function inspectReadySnapshot(bridge, sendTimeoutMs, simId) {
765
+ const result = await sendReadyWait(bridge, 1, sendTimeoutMs, simId);
766
+ return waitReadyStatus(result, result.probe ? readyProbeIsReady(result.probe) : false);
767
+ }
768
+ async function sendReadyWait(bridge, timeoutMs, sendTimeoutMs, simId) {
756
769
  const start = Date.now();
757
- let result;
758
770
  try {
759
- result = await bridge.send(
771
+ return await bridge.send(
760
772
  {
761
773
  type: "waitFor",
762
- ...options.simId ? { simId: options.simId } : {},
774
+ ...simId ? { simId } : {},
763
775
  waitForOptions: { condition: { type: "ready" }, timeoutMs }
764
776
  },
765
- { timeoutMs: timeoutMs + 1e3 }
777
+ { timeoutMs: sendTimeoutMs }
766
778
  );
767
779
  } catch (error) {
768
780
  const bridgeError = error instanceof Error ? error.message : String(error);
769
781
  if (bridgeError.startsWith("multiple sims are connected:") || bridgeError.startsWith("saved sim ")) {
770
782
  throw error;
771
783
  }
772
- result = {
773
- matched: false,
774
- elapsedMs: Date.now() - start,
775
- polls: 0,
776
- error: bridgeError
777
- };
784
+ return { matched: false, elapsedMs: Date.now() - start, polls: 0, error: bridgeError };
778
785
  }
786
+ }
787
+ function waitReadyStatus(result, ready) {
779
788
  const probe = result.probe;
780
- const externalError = probe?.externalError ?? "";
781
- const status = {
782
- ready: result.matched && !externalError,
789
+ return {
790
+ ready,
783
791
  elapsedMs: result.elapsedMs,
784
792
  nodes: probe?.nodes ?? 0,
785
793
  targets: probe?.targets ?? 0,
@@ -790,13 +798,11 @@ async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
790
798
  loadingText: probe?.loadingText ?? "",
791
799
  externalReady: probe?.externalReady ?? null,
792
800
  externalStatus: probe?.externalStatus ?? "",
793
- externalError,
801
+ externalError: probe?.externalError ?? "",
794
802
  suppressedEntryError: probe?.suppressedEntryError ?? "",
795
803
  errors: probe?.errors ?? 0,
796
804
  bridgeError: result.error ?? ""
797
805
  };
798
- if (!status.ready && options.onProgress) options.onProgress(status);
799
- return status;
800
806
  }
801
807
  async function inspectWaitSelector(bridge, testId, timeoutMs = 5e3, opts = {}) {
802
808
  const gone = opts.gone === true;
@@ -1583,6 +1589,34 @@ async function waitForSootsimIdle({
1583
1589
  blockedBy: typeof blockedBy === "string" ? blockedBy : "unknown"
1584
1590
  };
1585
1591
  }
1592
+ async function waitReadyAndSettle(bridge, timeoutMs, options = {}) {
1593
+ const start = Date.now();
1594
+ const remaining = () => Math.max(0, start + timeoutMs - Date.now());
1595
+ const result = (status, idle2) => ({
1596
+ status,
1597
+ idle: idle2,
1598
+ elapsedMs: Date.now() - start
1599
+ });
1600
+ let idle = null;
1601
+ for (; ; ) {
1602
+ const ready = await inspectWaitReady(bridge, remaining(), options);
1603
+ if (!ready.ready) return result(ready, idle);
1604
+ idle = await waitForSootsimIdle({
1605
+ bridge,
1606
+ simId: options.simId,
1607
+ maxMs: Math.min(1e4, remaining()),
1608
+ pollMs: 32,
1609
+ stablePolls: 2
1610
+ });
1611
+ if (!idle.settled) return result(ready, idle);
1612
+ const settled = await inspectReadySnapshot(
1613
+ bridge,
1614
+ Math.max(1e3, remaining()),
1615
+ options.simId
1616
+ );
1617
+ if (settled.ready || remaining() === 0) return result(settled, idle);
1618
+ }
1619
+ }
1586
1620
 
1587
1621
  // cli/commands/inspect/actions.ts
1588
1622
  var DEFAULT_AGENT_TIMING = {
@@ -2481,6 +2515,7 @@ export {
2481
2515
  inspectLogs,
2482
2516
  inspectMemory,
2483
2517
  inspectNodeCount,
2518
+ inspectReadySnapshot,
2484
2519
  inspectRequests,
2485
2520
  inspectScreens,
2486
2521
  inspectScrollStateAt,
@@ -2503,6 +2538,7 @@ export {
2503
2538
  rankInteractive,
2504
2539
  readyProbeHasContent,
2505
2540
  readyProbeHasTargetContent,
2541
+ readyProbeIsReady,
2506
2542
  resolveFindMode,
2507
2543
  resolveMaxMsFlag,
2508
2544
  scoreInteractive,
@@ -2518,5 +2554,6 @@ export {
2518
2554
  tapResolvedTarget,
2519
2555
  tapTargetFromPayload,
2520
2556
  waitForSootsimIdle,
2557
+ waitReadyAndSettle,
2521
2558
  waitReadyReason
2522
2559
  };