peachsim 0.1.663 → 0.1.665

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 (83) hide show
  1. package/cli/app-fonts.ts +6 -3
  2. package/cli/commands/control.ts +27 -19
  3. package/cli/commands/inspect/core.ts +58 -32
  4. package/cli/commands/inspect/settling.ts +27 -21
  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 +2 -6
  16. package/dist-lib/bridge-contract-input.mjs +2 -6
  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 +2191 -335
  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 +7 -7
  37. package/dist-lib/host/websocket-proxy.cjs +1 -1
  38. package/dist-lib/index.cjs +23 -30
  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 +1 -1
  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 +7 -7
  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 +56 -39
  60. package/dist-lib/sdk.mjs +54 -39
  61. package/dist-lib/skills.cjs +2803 -974
  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 +7 -7
  71. package/kotlin/ComposeSources/PeachComposeHost.kt +6 -3
  72. package/kotlin/fixtures/kotlin-app-variants/Overlays.kt +56 -0
  73. package/kotlin/fixtures/kotlin-app-variants/Scroll.kt +63 -0
  74. package/kotlin/fixtures/kotlin-app-variants/Sheet.kt +43 -0
  75. package/kotlin/fixtures/kotlin-app-variants/Tabs.kt +47 -0
  76. package/kotlin/fixtures/kotlin-app-variants/Widgets.kt +67 -0
  77. package/package.json +2 -2
  78. package/skills/peach-setup/SKILL.md +1 -1
  79. package/src/bridge-contract-input.ts +1 -5
  80. package/src/bridge-contract.ts +16 -4
  81. package/src/expo-swift-host.ts +248 -0
  82. package/src/host/bridge-host.ts +19 -0
  83. package/src/vite-plugin.ts +3 -3
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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;
@@ -170,12 +170,12 @@ function transformsFor(filePath) {
170
170
  function isLocalSpecifier(specifier) {
171
171
  return specifier.startsWith("./") || specifier.startsWith("../");
172
172
  }
173
- function isContrastKitSpecifier(specifier) {
174
- return specifier === "contrast-kit" || specifier.startsWith("contrast-kit/");
173
+ function isPeachKitSpecifier(specifier) {
174
+ return specifier === "peach-kit" || specifier.startsWith("peach-kit/");
175
175
  }
176
176
  function unsupportedSpecifier(specifier) {
177
177
  return new Error(
178
- `replacement modules may only import react, react-native, contrast-kit, the packages rnx stubs for this app, and other project files by relative path; '${specifier}' is none of those. vendor the code into a project file, or add the package to peach.config so the simulator bridges it.`
178
+ `replacement modules may only import react, react-native, peach-kit, the packages rnx stubs for this app, and other project files by relative path; '${specifier}' is none of those. vendor the code into a project file, or add the package to peach.config so the simulator bridges it.`
179
179
  );
180
180
  }
181
181
  function bridgeDeclaration(name, specifier) {
@@ -186,8 +186,8 @@ function bridgeDeclaration(name, specifier) {
186
186
  if (specifier === "react-native") {
187
187
  return `const ${name} = ${REACT_NATIVE_BRIDGE}; if (!${name}) throw new Error(${notReady("React Native")});`;
188
188
  }
189
- if (isContrastKitSpecifier(specifier)) {
190
- return `const ${name} = (globalThis.__contrast_kit_modules && globalThis.__contrast_kit_modules[${JSON.stringify(specifier)}]) || (${PACKAGE_BRIDGES} || {})[${JSON.stringify(specifier)}]; if (!${name}) throw new Error(${JSON.stringify(`[peach] replacement package bridge ${specifier} is not ready`)});`;
189
+ if (isPeachKitSpecifier(specifier)) {
190
+ return `const ${name} = (globalThis.__peach_kit_modules && globalThis.__peach_kit_modules[${JSON.stringify(specifier)}]) || (${PACKAGE_BRIDGES} || {})[${JSON.stringify(specifier)}]; if (!${name}) throw new Error(${JSON.stringify(`[peach] replacement package bridge ${specifier} is not ready`)});`;
191
191
  }
192
192
  if (JSX_RUNTIME_SPECIFIERS.has(specifier)) {
193
193
  return `const ${name} = (() => { const react = ${REACT_BRIDGE}; if (!react) throw new Error(${notReady("React")}); const jsx = (type, props, key) => react.createElement(type, key === undefined ? props : { ...props, key }); return { Fragment: react.Fragment, jsx, jsxs: jsx, jsxDEV: jsx }; })();`;
@@ -315,7 +315,7 @@ function compileReplacementModule(input) {
315
315
  pointAtLocalModule(specifierToken, specifier);
316
316
  continue;
317
317
  }
318
- if (specifier !== "react" && specifier !== "react-native" && !JSX_RUNTIME_SPECIFIERS.has(specifier) && !isContrastKitSpecifier(specifier) && !input.runtimePackages.has(specifier)) {
318
+ if (specifier !== "react" && specifier !== "react-native" && !JSX_RUNTIME_SPECIFIERS.has(specifier) && !isPeachKitSpecifier(specifier) && !input.runtimePackages.has(specifier)) {
319
319
  throw unsupportedSpecifier(specifier);
320
320
  }
321
321
  const bridge = bindings.length > 0 ? bridgeFor(specifier) : null;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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,39 +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 } : {},
1934
- waitForOptions: {
1935
- condition: {
1936
- type: "ready",
1937
- ...options.stableMs === void 0 ? {} : { stableMs: options.stableMs }
1938
- },
1939
- timeoutMs
1940
- }
1938
+ ...simId ? { simId } : {},
1939
+ waitForOptions: { condition: { type: "ready" }, timeoutMs }
1941
1940
  },
1942
- { timeoutMs: timeoutMs + 1e3 }
1941
+ { timeoutMs: sendTimeoutMs }
1943
1942
  );
1944
1943
  } catch (error) {
1945
1944
  const bridgeError = error instanceof Error ? error.message : String(error);
1946
1945
  if (bridgeError.startsWith("multiple sims are connected:") || bridgeError.startsWith("saved sim ")) {
1947
1946
  throw error;
1948
1947
  }
1949
- result = {
1950
- matched: false,
1951
- elapsedMs: Date.now() - start,
1952
- polls: 0,
1953
- error: bridgeError
1954
- };
1948
+ return { matched: false, elapsedMs: Date.now() - start, polls: 0, error: bridgeError };
1955
1949
  }
1950
+ }
1951
+ function waitReadyStatus(result, ready) {
1956
1952
  const probe = result.probe;
1957
- const externalError = probe?.externalError ?? "";
1958
- const status = {
1959
- ready: result.matched && !externalError,
1953
+ return {
1954
+ ready,
1960
1955
  elapsedMs: result.elapsedMs,
1961
1956
  nodes: probe?.nodes ?? 0,
1962
1957
  targets: probe?.targets ?? 0,
@@ -1967,13 +1962,11 @@ async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
1967
1962
  loadingText: probe?.loadingText ?? "",
1968
1963
  externalReady: probe?.externalReady ?? null,
1969
1964
  externalStatus: probe?.externalStatus ?? "",
1970
- externalError,
1965
+ externalError: probe?.externalError ?? "",
1971
1966
  suppressedEntryError: probe?.suppressedEntryError ?? "",
1972
1967
  errors: probe?.errors ?? 0,
1973
1968
  bridgeError: result.error ?? ""
1974
1969
  };
1975
- if (!status.ready && options.onProgress) options.onProgress(status);
1976
- return status;
1977
1970
  }
1978
1971
  function consoleEntriesEval(level, limit) {
1979
1972
  const getter = level === "error" ? "getErrors" : "getWarnings";
@@ -3749,12 +3742,12 @@ function transformsFor(filePath) {
3749
3742
  function isLocalSpecifier(specifier) {
3750
3743
  return specifier.startsWith("./") || specifier.startsWith("../");
3751
3744
  }
3752
- function isContrastKitSpecifier(specifier) {
3753
- return specifier === "contrast-kit" || specifier.startsWith("contrast-kit/");
3745
+ function isPeachKitSpecifier(specifier) {
3746
+ return specifier === "peach-kit" || specifier.startsWith("peach-kit/");
3754
3747
  }
3755
3748
  function unsupportedSpecifier(specifier) {
3756
3749
  return new Error(
3757
- `replacement modules may only import react, react-native, contrast-kit, the packages rnx stubs for this app, and other project files by relative path; '${specifier}' is none of those. vendor the code into a project file, or add the package to peach.config so the simulator bridges it.`
3750
+ `replacement modules may only import react, react-native, peach-kit, the packages rnx stubs for this app, and other project files by relative path; '${specifier}' is none of those. vendor the code into a project file, or add the package to peach.config so the simulator bridges it.`
3758
3751
  );
3759
3752
  }
3760
3753
  function bridgeDeclaration(name2, specifier) {
@@ -3765,8 +3758,8 @@ function bridgeDeclaration(name2, specifier) {
3765
3758
  if (specifier === "react-native") {
3766
3759
  return `const ${name2} = ${REACT_NATIVE_BRIDGE}; if (!${name2}) throw new Error(${notReady("React Native")});`;
3767
3760
  }
3768
- if (isContrastKitSpecifier(specifier)) {
3769
- return `const ${name2} = (globalThis.__contrast_kit_modules && globalThis.__contrast_kit_modules[${JSON.stringify(specifier)}]) || (${PACKAGE_BRIDGES} || {})[${JSON.stringify(specifier)}]; if (!${name2}) throw new Error(${JSON.stringify(`[peach] replacement package bridge ${specifier} is not ready`)});`;
3761
+ if (isPeachKitSpecifier(specifier)) {
3762
+ return `const ${name2} = (globalThis.__peach_kit_modules && globalThis.__peach_kit_modules[${JSON.stringify(specifier)}]) || (${PACKAGE_BRIDGES} || {})[${JSON.stringify(specifier)}]; if (!${name2}) throw new Error(${JSON.stringify(`[peach] replacement package bridge ${specifier} is not ready`)});`;
3770
3763
  }
3771
3764
  if (JSX_RUNTIME_SPECIFIERS.has(specifier)) {
3772
3765
  return `const ${name2} = (() => { const react = ${REACT_BRIDGE}; if (!react) throw new Error(${notReady("React")}); const jsx = (type, props, key) => react.createElement(type, key === undefined ? props : { ...props, key }); return { Fragment: react.Fragment, jsx, jsxs: jsx, jsxDEV: jsx }; })();`;
@@ -3894,7 +3887,7 @@ function compileReplacementModule(input) {
3894
3887
  pointAtLocalModule(specifierToken, specifier);
3895
3888
  continue;
3896
3889
  }
3897
- if (specifier !== "react" && specifier !== "react-native" && !JSX_RUNTIME_SPECIFIERS.has(specifier) && !isContrastKitSpecifier(specifier) && !input.runtimePackages.has(specifier)) {
3890
+ if (specifier !== "react" && specifier !== "react-native" && !JSX_RUNTIME_SPECIFIERS.has(specifier) && !isPeachKitSpecifier(specifier) && !input.runtimePackages.has(specifier)) {
3898
3891
  throw unsupportedSpecifier(specifier);
3899
3892
  }
3900
3893
  const bridge = bindings.length > 0 ? bridgeFor(specifier) : null;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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;
@@ -195,12 +195,12 @@ function transformsFor(filePath) {
195
195
  function isLocalSpecifier(specifier) {
196
196
  return specifier.startsWith("./") || specifier.startsWith("../");
197
197
  }
198
- function isContrastKitSpecifier(specifier) {
199
- return specifier === "contrast-kit" || specifier.startsWith("contrast-kit/");
198
+ function isPeachKitSpecifier(specifier) {
199
+ return specifier === "peach-kit" || specifier.startsWith("peach-kit/");
200
200
  }
201
201
  function unsupportedSpecifier(specifier) {
202
202
  return new Error(
203
- `replacement modules may only import react, react-native, contrast-kit, the packages rnx stubs for this app, and other project files by relative path; '${specifier}' is none of those. vendor the code into a project file, or add the package to peach.config so the simulator bridges it.`
203
+ `replacement modules may only import react, react-native, peach-kit, the packages rnx stubs for this app, and other project files by relative path; '${specifier}' is none of those. vendor the code into a project file, or add the package to peach.config so the simulator bridges it.`
204
204
  );
205
205
  }
206
206
  function bridgeDeclaration(name, specifier) {
@@ -211,8 +211,8 @@ function bridgeDeclaration(name, specifier) {
211
211
  if (specifier === "react-native") {
212
212
  return `const ${name} = ${REACT_NATIVE_BRIDGE}; if (!${name}) throw new Error(${notReady("React Native")});`;
213
213
  }
214
- if (isContrastKitSpecifier(specifier)) {
215
- return `const ${name} = (globalThis.__contrast_kit_modules && globalThis.__contrast_kit_modules[${JSON.stringify(specifier)}]) || (${PACKAGE_BRIDGES} || {})[${JSON.stringify(specifier)}]; if (!${name}) throw new Error(${JSON.stringify(`[peach] replacement package bridge ${specifier} is not ready`)});`;
214
+ if (isPeachKitSpecifier(specifier)) {
215
+ return `const ${name} = (globalThis.__peach_kit_modules && globalThis.__peach_kit_modules[${JSON.stringify(specifier)}]) || (${PACKAGE_BRIDGES} || {})[${JSON.stringify(specifier)}]; if (!${name}) throw new Error(${JSON.stringify(`[peach] replacement package bridge ${specifier} is not ready`)});`;
216
216
  }
217
217
  if (JSX_RUNTIME_SPECIFIERS.has(specifier)) {
218
218
  return `const ${name} = (() => { const react = ${REACT_BRIDGE}; if (!react) throw new Error(${notReady("React")}); const jsx = (type, props, key) => react.createElement(type, key === undefined ? props : { ...props, key }); return { Fragment: react.Fragment, jsx, jsxs: jsx, jsxDEV: jsx }; })();`;
@@ -340,7 +340,7 @@ function compileReplacementModule(input) {
340
340
  pointAtLocalModule(specifierToken, specifier);
341
341
  continue;
342
342
  }
343
- if (specifier !== "react" && specifier !== "react-native" && !JSX_RUNTIME_SPECIFIERS.has(specifier) && !isContrastKitSpecifier(specifier) && !input.runtimePackages.has(specifier)) {
343
+ if (specifier !== "react" && specifier !== "react-native" && !JSX_RUNTIME_SPECIFIERS.has(specifier) && !isPeachKitSpecifier(specifier) && !input.runtimePackages.has(specifier)) {
344
344
  throw unsupportedSpecifier(specifier);
345
345
  }
346
346
  const bridge = bindings.length > 0 ? bridgeFor(specifier) : null;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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.663 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.665 | (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,
@@ -114,6 +116,9 @@ function readyProbeHasContent(probe) {
114
116
  function readyProbeHasTargetContent(probe) {
115
117
  return probe.liveFrameActive || probe.targets > 0;
116
118
  }
119
+ function readyProbeIsReady(probe) {
120
+ return (probe.flag === true ? readyProbeHasContent(probe) : readyProbeHasTargetContent(probe)) && probe.externalReady !== false && !probe.externalError && !probe.loadingText;
121
+ }
117
122
 
118
123
  // cli/commands/inspect/core.ts
119
124
  function resolveMaxMsFlag(args, fallbackMs) {
@@ -854,39 +859,46 @@ function waitReadyReason(status) {
854
859
  return !status.externalError && status.suppressedEntryError ? `${base} (suppressed entry error: ${status.suppressedEntryError})` : base;
855
860
  }
856
861
  async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
857
- const start = Date.now();
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
+ var READY_SNAPSHOT_SEND_TIMEOUT_MS = 2e3;
868
+ async function inspectReadySnapshot(bridge, budgetMs, simId) {
869
+ const deadline = Date.now() + budgetMs;
858
870
  let result;
871
+ do {
872
+ result = await sendReadyWait(bridge, 1, READY_SNAPSHOT_SEND_TIMEOUT_MS, simId);
873
+ } while (result.polls !== 1 && !result.error && Date.now() < deadline);
874
+ return waitReadyStatus(
875
+ result,
876
+ result.polls === 1 && result.probe ? readyProbeIsReady(result.probe) : false
877
+ );
878
+ }
879
+ async function sendReadyWait(bridge, timeoutMs, sendTimeoutMs, simId) {
880
+ const start = Date.now();
859
881
  try {
860
- result = await bridge.send(
882
+ return await bridge.send(
861
883
  {
862
884
  type: "waitFor",
863
- ...options.simId ? { simId: options.simId } : {},
864
- waitForOptions: {
865
- condition: {
866
- type: "ready",
867
- ...options.stableMs === void 0 ? {} : { stableMs: options.stableMs }
868
- },
869
- timeoutMs
870
- }
885
+ ...simId ? { simId } : {},
886
+ waitForOptions: { condition: { type: "ready" }, timeoutMs }
871
887
  },
872
- { timeoutMs: timeoutMs + 1e3 }
888
+ { timeoutMs: sendTimeoutMs }
873
889
  );
874
890
  } catch (error) {
875
891
  const bridgeError = error instanceof Error ? error.message : String(error);
876
892
  if (bridgeError.startsWith("multiple sims are connected:") || bridgeError.startsWith("saved sim ")) {
877
893
  throw error;
878
894
  }
879
- result = {
880
- matched: false,
881
- elapsedMs: Date.now() - start,
882
- polls: 0,
883
- error: bridgeError
884
- };
895
+ return { matched: false, elapsedMs: Date.now() - start, polls: 0, error: bridgeError };
885
896
  }
897
+ }
898
+ function waitReadyStatus(result, ready) {
886
899
  const probe = result.probe;
887
- const externalError = probe?.externalError ?? "";
888
- const status = {
889
- ready: result.matched && !externalError,
900
+ return {
901
+ ready,
890
902
  elapsedMs: result.elapsedMs,
891
903
  nodes: probe?.nodes ?? 0,
892
904
  targets: probe?.targets ?? 0,
@@ -897,13 +909,11 @@ async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
897
909
  loadingText: probe?.loadingText ?? "",
898
910
  externalReady: probe?.externalReady ?? null,
899
911
  externalStatus: probe?.externalStatus ?? "",
900
- externalError,
912
+ externalError: probe?.externalError ?? "",
901
913
  suppressedEntryError: probe?.suppressedEntryError ?? "",
902
914
  errors: probe?.errors ?? 0,
903
915
  bridgeError: result.error ?? ""
904
916
  };
905
- if (!status.ready && options.onProgress) options.onProgress(status);
906
- return status;
907
917
  }
908
918
  async function inspectWaitSelector(bridge, testId, timeoutMs = 5e3, opts = {}) {
909
919
  const gone = opts.gone === true;
@@ -1692,22 +1702,27 @@ async function waitForSootsimIdle({
1692
1702
  }
1693
1703
  async function waitReadyAndSettle(bridge, timeoutMs, options = {}) {
1694
1704
  const start = Date.now();
1695
- const ready = await inspectWaitReady(bridge, timeoutMs, options);
1696
- if (!ready.ready) return { status: ready, idle: null, elapsedMs: Date.now() - start };
1697
- const idle = await waitForSootsimIdle({
1698
- bridge,
1699
- simId: options.simId,
1700
- maxMs: Math.max(100, Math.min(1e4, timeoutMs - (Date.now() - start))),
1701
- pollMs: 32,
1702
- stablePolls: 2
1705
+ const remaining = () => Math.max(0, start + timeoutMs - Date.now());
1706
+ const result = (status, idle2) => ({
1707
+ status,
1708
+ idle: idle2,
1709
+ elapsedMs: Date.now() - start
1703
1710
  });
1704
- if (!idle.settled) return { status: ready, idle, elapsedMs: Date.now() - start };
1705
- const settled = await inspectWaitReady(
1706
- bridge,
1707
- Math.max(1e3, timeoutMs - (Date.now() - start)),
1708
- { ...options.simId ? { simId: options.simId } : {}, stableMs: 0 }
1709
- );
1710
- return { status: settled, idle, elapsedMs: Date.now() - start };
1711
+ let idle = null;
1712
+ for (; ; ) {
1713
+ const ready = await inspectWaitReady(bridge, remaining(), options);
1714
+ if (!ready.ready) return result(ready, idle);
1715
+ idle = await waitForSootsimIdle({
1716
+ bridge,
1717
+ simId: options.simId,
1718
+ maxMs: Math.min(1e4, remaining()),
1719
+ pollMs: 32,
1720
+ stablePolls: 2
1721
+ });
1722
+ if (!idle.settled) return result(ready, idle);
1723
+ const settled = await inspectReadySnapshot(bridge, remaining(), options.simId);
1724
+ if (settled.ready || remaining() === 0) return result(settled, idle);
1725
+ }
1711
1726
  }
1712
1727
 
1713
1728
  // cli/commands/inspect/actions.ts
@@ -2608,6 +2623,7 @@ var SimClient = class {
2608
2623
  inspectLogs,
2609
2624
  inspectMemory,
2610
2625
  inspectNodeCount,
2626
+ inspectReadySnapshot,
2611
2627
  inspectRequests,
2612
2628
  inspectScreens,
2613
2629
  inspectScrollStateAt,
@@ -2630,6 +2646,7 @@ var SimClient = class {
2630
2646
  rankInteractive,
2631
2647
  readyProbeHasContent,
2632
2648
  readyProbeHasTargetContent,
2649
+ readyProbeIsReady,
2633
2650
  resolveFindMode,
2634
2651
  resolveMaxMsFlag,
2635
2652
  scoreInteractive,