peachsim 0.1.629 → 0.1.630

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 (110) hide show
  1. package/README.md +8 -4
  2. package/cli/bridge-flow-runner.ts +10 -3
  3. package/cli/cli-update.ts +2 -7
  4. package/cli/cloud-test-tunnel.ts +16 -3
  5. package/cli/commands/config.ts +1 -1
  6. package/cli/commands/control.ts +28 -3
  7. package/cli/commands/daemon-mac-app.ts +4 -2
  8. package/cli/commands/daemon.ts +4 -4
  9. package/cli/commands/device.ts +2 -3
  10. package/cli/commands/inspect/actions.ts +125 -90
  11. package/cli/commands/inspect.ts +6 -1
  12. package/cli/commands/platform.ts +1 -1
  13. package/cli/commands/screenshot-layers.ts +1 -1
  14. package/cli/commands/screenshot.ts +1 -1
  15. package/cli/commands/skills.ts +0 -31
  16. package/cli/drivers/playwright-provisioning.ts +3 -2
  17. package/cli/drivers/playwright-sim-host.ts +25 -9
  18. package/cli/main.ts +8 -2
  19. package/cli/outbound-endpoints.ts +0 -4
  20. package/detox/index.ts +74 -43
  21. package/dist-lib/agent-daemon-client.cjs +1 -1
  22. package/dist-lib/agent-events.cjs +1 -1
  23. package/dist-lib/agent-identity.cjs +1 -1
  24. package/dist-lib/agent-sessions.cjs +1 -1
  25. package/dist-lib/attached-projects.cjs +1 -1
  26. package/dist-lib/auth/shared-session.cjs +1 -1
  27. package/dist-lib/backend-origin.cjs +1 -1
  28. package/dist-lib/beta.cjs +1 -1
  29. package/dist-lib/beta.mjs +1 -1
  30. package/dist-lib/bridge-constants.cjs +1 -1
  31. package/dist-lib/bridge-contract-input.cjs +1 -1
  32. package/dist-lib/bridge-contract-input.mjs +1 -1
  33. package/dist-lib/bridge-contract.cjs +1 -1
  34. package/dist-lib/bridge-contract.mjs +1 -1
  35. package/dist-lib/capture-contract.cjs +1 -1
  36. package/dist-lib/capture-contract.mjs +1 -1
  37. package/dist-lib/cli-constants.cjs +1 -1
  38. package/dist-lib/cloud-contract.cjs +1 -1
  39. package/dist-lib/cloud-contract.mjs +1 -1
  40. package/dist-lib/cloud-test-args.cjs +1 -1
  41. package/dist-lib/cloud-test-args.mjs +1 -1
  42. package/dist-lib/cloud.cjs +1 -1
  43. package/dist-lib/cloud.mjs +1 -1
  44. package/dist-lib/config.cjs +1 -1
  45. package/dist-lib/detox/index.cjs +129 -27
  46. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  47. package/dist-lib/home-paths.cjs +1 -1
  48. package/dist-lib/host/bridge-host.cjs +275 -255
  49. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  50. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  51. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  52. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  53. package/dist-lib/host/websocket-proxy.cjs +1 -1
  54. package/dist-lib/index.cjs +253 -121
  55. package/dist-lib/jump-to-source-babel.cjs +1 -1
  56. package/dist-lib/jump-to-source-native.cjs +1 -1
  57. package/dist-lib/{vite-kotlin.cjs → kotlin-host.cjs} +130 -19
  58. package/dist-lib/menu.cjs +1 -1
  59. package/dist-lib/menu.mjs +1 -1
  60. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  61. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  62. package/dist-lib/metro-production-bundle.cjs +1 -1
  63. package/dist-lib/metro-production-bundle.mjs +1 -1
  64. package/dist-lib/metro.cjs +132 -9
  65. package/dist-lib/native-app-identity.cjs +278 -0
  66. package/dist-lib/native-app-identity.mjs +245 -0
  67. package/dist-lib/profiles.cjs +1 -1
  68. package/dist-lib/public-brand.cjs +1 -1
  69. package/dist-lib/react-native-host-modules.cjs +1 -1
  70. package/dist-lib/react-native-host-modules.mjs +1 -1
  71. package/dist-lib/render-mode.cjs +1 -1
  72. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  73. package/dist-lib/sdk.cjs +110 -87
  74. package/dist-lib/sdk.mjs +110 -87
  75. package/dist-lib/skills.cjs +822 -582
  76. package/dist-lib/swift-compile.cjs +1 -1
  77. package/dist-lib/swift-compile.mjs +1 -1
  78. package/dist-lib/swift-package.cjs +1 -1
  79. package/dist-lib/swift-package.mjs +1 -1
  80. package/dist-lib/swift-submit.cjs +1 -1
  81. package/dist-lib/swift-submit.mjs +1 -1
  82. package/dist-lib/swift.cjs +234 -109
  83. package/dist-lib/vite-swift.cjs +1 -1
  84. package/dist-lib/vite.cjs +11 -28
  85. package/kotlin/README.md +32 -4
  86. package/kotlin/fixtures/counter/Counter.kt +26 -0
  87. package/kotlin/fixtures/counter/CounterScreen.kt +40 -0
  88. package/kotlin/fixtures/headless-counter/Headless.kt +228 -0
  89. package/kotlin/fixtures/runtime-state/RuntimeState.kt +200 -0
  90. package/kotlin/fork/LICENSE +178 -0
  91. package/kotlin/fork/NOTICE +25 -0
  92. package/kotlin/fork/README.md +59 -0
  93. package/kotlin/fork/build.sh +128 -0
  94. package/kotlin/fork/compose-worker-globals.patch +96 -0
  95. package/kotlin/fork/fork.json +33 -0
  96. package/kotlin/fork/publish.ts +77 -0
  97. package/kotlin/fork/skiko-worker-clock.patch +33 -0
  98. package/kotlin/toolchain.json +288 -0
  99. package/package.json +12 -5
  100. package/src/automatic-update-policy.ts +17 -0
  101. package/src/host/bridge-host.ts +3 -1
  102. package/src/{vite-plugin-kotlin.ts → kotlin-host.ts} +155 -12
  103. package/src/metro-plugin.ts +18 -0
  104. package/src/native-app-identity.ts +376 -0
  105. package/src/native-firebase-config.ts +90 -0
  106. package/src/screenshots/frame-compose.ts +1 -1
  107. package/src/screenshots/registry.ts +1 -1
  108. package/src/screenshots/schema.ts +2 -2
  109. package/src/vite-plugin-one.ts +11 -28
  110. package/src/vite-plugin.ts +6 -1
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.629 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.630 | (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;
@@ -6711,6 +6711,10 @@ var COLOR_STYLE_PROPS = /* @__PURE__ */ new Set([
6711
6711
  "borderRightColor",
6712
6712
  "borderStartColor",
6713
6713
  "borderEndColor",
6714
+ "borderBlockColor",
6715
+ "borderBlockStartColor",
6716
+ "borderBlockEndColor",
6717
+ "overlayColor",
6714
6718
  "textDecorationColor",
6715
6719
  "textShadowColor",
6716
6720
  "tintColor",
@@ -7453,12 +7457,14 @@ function isMetroAssetRegistryModulePath(modulePath) {
7453
7457
  return modulePath.includes("polyfill:assets-registry") || modulePath.includes("@react-native/assets-registry/registry") || modulePath.includes("assets-registry/registry") || modulePath.includes("react-native/asset-registry") || modulePath.includes("react-native/src/asset-registry");
7454
7458
  }
7455
7459
 
7460
+ // ../peach-compat/src/stubs/browser-object-url.ts
7461
+ var BrowserURL = globalThis.URL;
7462
+ var createBrowserObjectURL = BrowserURL.createObjectURL.bind(BrowserURL);
7463
+ var revokeBrowserObjectURL = BrowserURL.revokeObjectURL.bind(BrowserURL);
7464
+
7456
7465
  // ../peach-engine/src/native-globals.ts
7457
7466
  var nativeGlobals = globalThis;
7458
7467
  var NativeBlob = nativeGlobals.Blob;
7459
- var NativeURL = nativeGlobals.URL;
7460
- var nativeCreateObjectURL = URL.createObjectURL.bind(URL);
7461
- var nativeRevokeObjectURL = URL.revokeObjectURL.bind(URL);
7462
7468
  var NativeTextDecoder = nativeGlobals.TextDecoder;
7463
7469
  var NativeTextEncoder = nativeGlobals.TextEncoder;
7464
7470
  var NativeXMLHttpRequest = nativeGlobals.XMLHttpRequest;
@@ -7480,36 +7486,6 @@ var nativeMatchMedia = typeof window !== "undefined" && typeof window.matchMedia
7480
7486
  return false;
7481
7487
  }
7482
7488
  }));
7483
- function installBlobLock() {
7484
- const desc = Object.getOwnPropertyDescriptor(URL, "createObjectURL");
7485
- if (desc && desc.configurable === false && desc.get) {
7486
- return;
7487
- }
7488
- try {
7489
- Object.defineProperty(URL, "createObjectURL", {
7490
- configurable: false,
7491
- enumerable: false,
7492
- get() {
7493
- return nativeCreateObjectURL;
7494
- },
7495
- set(_) {
7496
- }
7497
- });
7498
- } catch {
7499
- }
7500
- try {
7501
- Object.defineProperty(URL, "revokeObjectURL", {
7502
- configurable: false,
7503
- enumerable: false,
7504
- get() {
7505
- return nativeRevokeObjectURL;
7506
- },
7507
- set(_) {
7508
- }
7509
- });
7510
- } catch {
7511
- }
7512
- }
7513
7489
  function installMatchMediaLock() {
7514
7490
  const g = globalThis;
7515
7491
  const desc = Object.getOwnPropertyDescriptor(g, "matchMedia");
@@ -7554,9 +7530,6 @@ function installNetworkingLock() {
7554
7530
  installCodecOrNetGlobalLock("XMLHttpRequest", NativeXMLHttpRequest);
7555
7531
  installCodecOrNetGlobalLock("FormData", NativeFormData);
7556
7532
  }
7557
- function installURLLock() {
7558
- installCodecOrNetGlobalLock("URL", NativeURL);
7559
- }
7560
7533
  function restoreNativeBlobHelpers() {
7561
7534
  const g = globalThis;
7562
7535
  if (g.Blob !== NativeBlob) {
@@ -7565,11 +7538,9 @@ function restoreNativeBlobHelpers() {
7565
7538
  } catch {
7566
7539
  }
7567
7540
  }
7568
- installBlobLock();
7569
7541
  installTextCodecLock();
7570
7542
  installMatchMediaLock();
7571
7543
  installNetworkingLock();
7572
- installURLLock();
7573
7544
  }
7574
7545
  restoreNativeBlobHelpers();
7575
7546
  var LOCKED_GLOBALS = /* @__PURE__ */ new Set([
@@ -7577,8 +7548,7 @@ var LOCKED_GLOBALS = /* @__PURE__ */ new Set([
7577
7548
  "TextEncoder",
7578
7549
  "Blob",
7579
7550
  "XMLHttpRequest",
7580
- "FormData",
7581
- "URL"
7551
+ "FormData"
7582
7552
  ]);
7583
7553
  function patchedDefineProperty(target, key, descriptor) {
7584
7554
  const onGlobal = target === globalThis;
@@ -10052,6 +10022,57 @@ var INLINE_STYLE_PROP_KEYS = [
10052
10022
  "transform"
10053
10023
  ];
10054
10024
  var INLINE_STYLE_PROP_SET = new Set(INLINE_STYLE_PROP_KEYS);
10025
+ var FABRIC_STYLE_PROP_SET = /* @__PURE__ */ new Set([
10026
+ ...INLINE_STYLE_PROP_SET,
10027
+ "insetBlock",
10028
+ "insetBlockEnd",
10029
+ "insetBlockStart",
10030
+ "insetInline",
10031
+ "insetInlineEnd",
10032
+ "insetInlineStart",
10033
+ "marginBlock",
10034
+ "marginBlockEnd",
10035
+ "marginBlockStart",
10036
+ "marginInline",
10037
+ "marginInlineEnd",
10038
+ "marginInlineStart",
10039
+ "paddingBlock",
10040
+ "paddingBlockEnd",
10041
+ "paddingBlockStart",
10042
+ "paddingInline",
10043
+ "paddingInlineEnd",
10044
+ "paddingInlineStart",
10045
+ "experimental_backgroundSize",
10046
+ "experimental_backgroundPosition",
10047
+ "experimental_backgroundRepeat",
10048
+ "backfaceVisibility",
10049
+ "borderBlockColor",
10050
+ "borderBlockEndColor",
10051
+ "borderBlockStartColor",
10052
+ "borderCurve",
10053
+ "borderEndEndRadius",
10054
+ "borderEndStartRadius",
10055
+ "borderStartEndRadius",
10056
+ "borderStartStartRadius",
10057
+ "borderTopEndRadius",
10058
+ "borderTopStartRadius",
10059
+ "cursor",
10060
+ "userSelect",
10061
+ "verticalAlign",
10062
+ "overlayColor",
10063
+ "resizeMode",
10064
+ "objectFit"
10065
+ ]);
10066
+ function mergeFabricRawProps(hostProps, rawProps) {
10067
+ const props = { ...hostProps };
10068
+ const style = {};
10069
+ for (const [key, value] of Object.entries(rawProps)) {
10070
+ if (FABRIC_STYLE_PROP_SET.has(key)) style[key] = value;
10071
+ else props[key] = value;
10072
+ }
10073
+ props.style = [hostProps.style, style];
10074
+ return props;
10075
+ }
10055
10076
  function extractOrderedStyleInput(type, props) {
10056
10077
  let out = null;
10057
10078
  let pending = null;
@@ -10367,6 +10388,9 @@ function resolveStyleValue(value, key) {
10367
10388
  if (typeof value === "boolean") return value;
10368
10389
  if (typeof value !== "object") return value;
10369
10390
  if (key && COLOR_STYLE_PROPS.has(key)) {
10391
+ if (value.space === "srgb") {
10392
+ return `rgba(${value.r * 255},${value.g * 255},${value.b * 255},${value.a})`;
10393
+ }
10370
10394
  const platformColor = resolveAndroidPlatformColor(value);
10371
10395
  if (platformColor) return normalizeColorStyleValue(key, platformColor);
10372
10396
  }
@@ -11596,7 +11620,8 @@ function attachNativeHostInstanceFields(node) {
11596
11620
  ["_nativeTag", node.id],
11597
11621
  ["__viewTag", node.id],
11598
11622
  ["__internalInstanceHandle", { stateNode: { node } }],
11599
- ["_viewConfig", viewConfig]
11623
+ ["_viewConfig", viewConfig],
11624
+ ["__viewConfig", viewConfig]
11600
11625
  ]) {
11601
11626
  Object.defineProperty(node, key, {
11602
11627
  value,
@@ -11751,6 +11776,8 @@ var SootSimNode = class _SootSimNode {
11751
11776
  id;
11752
11777
  type;
11753
11778
  props;
11779
+ lastReactProps;
11780
+ fabricNativeProps = null;
11754
11781
  // exact Tamagui token provenance for this node's resolved style, read from
11755
11782
  // the host style layers on ingestion (before flatten/resolve). empty for
11756
11783
  // ordinary React Native nodes; frozen into
@@ -11808,8 +11835,6 @@ var SootSimNode = class _SootSimNode {
11808
11835
  _scrollOffsetX = 0;
11809
11836
  _scrollOffsetY = 0;
11810
11837
  _scrollOffsetListeners = null;
11811
- _scrollFollowContentEndX = false;
11812
- _scrollFollowContentEndY = false;
11813
11838
  _maintainVisibleContentPositionAnchor = null;
11814
11839
  _maintainVisibleContentPositionAnchorFromMutation = false;
11815
11840
  // a scroll content container's children extent (engine/scroll.ts), valid
@@ -12047,6 +12072,19 @@ var SootSimNode = class _SootSimNode {
12047
12072
  return this.unstable_getBoundingClientRect();
12048
12073
  }
12049
12074
  // RN ref compatibility
12075
+ commitFabricRawProps(props) {
12076
+ let root = this;
12077
+ while (root.parent) root = root.parent;
12078
+ if (root === this || root.type !== "root") return null;
12079
+ this.updateProps(
12080
+ mergeFabricRawProps(
12081
+ { ...this.props, style: flattenStyle2(this.props.style) },
12082
+ props
12083
+ ),
12084
+ "native"
12085
+ );
12086
+ return root;
12087
+ }
12050
12088
  __setNativePropsImpl;
12051
12089
  __dispatchCommandImpl;
12052
12090
  markAnimatedNativePropKeys(props) {
@@ -12293,7 +12331,6 @@ var SootSimNode = class _SootSimNode {
12293
12331
  return;
12294
12332
  }
12295
12333
  if (this.scrollOffsetX === next) return;
12296
- this._scrollFollowContentEndX = false;
12297
12334
  this.scrollOffsetX = next;
12298
12335
  this.__scroll?.syncExternalOffset?.();
12299
12336
  this.markImperativeScrollDirty();
@@ -12314,7 +12351,6 @@ var SootSimNode = class _SootSimNode {
12314
12351
  return;
12315
12352
  }
12316
12353
  if (this.scrollOffsetY === next) return;
12317
- this._scrollFollowContentEndY = false;
12318
12354
  this.scrollOffsetY = next;
12319
12355
  this.__scroll?.syncExternalOffset?.();
12320
12356
  this.markImperativeScrollDirty();
@@ -12353,6 +12389,7 @@ var SootSimNode = class _SootSimNode {
12353
12389
  }
12354
12390
  }
12355
12391
  if (this.__scroll?.scrollToOffset) {
12392
+ this._flushPendingLayout();
12356
12393
  this.__scroll.scrollToOffset({
12357
12394
  ...hasX ? { x: nextLeft } : {},
12358
12395
  ...hasY ? { y: nextTop } : {},
@@ -12368,8 +12405,6 @@ var SootSimNode = class _SootSimNode {
12368
12405
  if (this.scrollOffsetX === nextLeft && this.scrollOffsetY === nextTop) {
12369
12406
  return;
12370
12407
  }
12371
- const requestedLeft = nextLeft;
12372
- const requestedTop = nextTop;
12373
12408
  const contentBounds = getScrollContentBounds(this);
12374
12409
  const maxScroll = getScrollContentEndOffset(this, this.props);
12375
12410
  const maxScrollX = maxScroll.x;
@@ -12388,12 +12423,6 @@ var SootSimNode = class _SootSimNode {
12388
12423
  ),
12389
12424
  Math.min(maxScrollY, nextTop)
12390
12425
  );
12391
- if (hasX) {
12392
- this._scrollFollowContentEndX = maxScrollX > 0 && requestedLeft >= maxScrollX - 0.5;
12393
- }
12394
- if (hasY) {
12395
- this._scrollFollowContentEndY = maxScrollY > 0 && requestedTop >= maxScrollY - 0.5;
12396
- }
12397
12426
  this.scrollOffsetX = nextLeft;
12398
12427
  this.scrollOffsetY = nextTop;
12399
12428
  this.__scroll?.syncExternalOffset?.();
@@ -12441,8 +12470,12 @@ var SootSimNode = class _SootSimNode {
12441
12470
  animated: arg1?.animated !== false
12442
12471
  });
12443
12472
  }
12473
+ // a command runs against the committed tree: fabric mounts a commit before
12474
+ // the ui thread runs a command issued after it (both queue on the main
12475
+ // queue), so a scrollToEnd from an effect sees the rows that commit added
12444
12476
  scrollToEnd(options) {
12445
12477
  if (this.__scroll?.scrollToOffset) {
12478
+ this._flushPendingLayout();
12446
12479
  const target = Number.MAX_SAFE_INTEGER;
12447
12480
  const opts = this.props?.horizontal === true ? { x: target, y: 0, animated: options?.animated !== false } : { x: 0, y: target, animated: options?.animated !== false };
12448
12481
  this.__scroll.scrollToOffset({
@@ -12677,6 +12710,7 @@ var SootSimNode = class _SootSimNode {
12677
12710
  );
12678
12711
  this.type = type;
12679
12712
  this.props = props;
12713
+ this.lastReactProps = props;
12680
12714
  if (type === "image") queueImageLoad(this);
12681
12715
  this._wireRevision = nextWireRevision();
12682
12716
  this._wireSubtreeRevision = this._wireRevision;
@@ -12752,7 +12786,26 @@ var SootSimNode = class _SootSimNode {
12752
12786
  }
12753
12787
  updateProps(newProps, source = "react") {
12754
12788
  if (source === "react") {
12789
+ if (this.fabricNativeProps) {
12790
+ const previous = {
12791
+ ...this.lastReactProps,
12792
+ ...flattenStyle2(getNodeStyleInput(this.type, this.lastReactProps))
12793
+ };
12794
+ const next = {
12795
+ ...newProps,
12796
+ ...flattenStyle2(getNodeStyleInput(this.type, newProps))
12797
+ };
12798
+ for (const key of Object.keys(this.fabricNativeProps)) {
12799
+ if (!styleValuesEqual(previous[key], next[key])) {
12800
+ this.fabricNativeProps[key] = next[key] ?? null;
12801
+ }
12802
+ }
12803
+ }
12804
+ this.lastReactProps = newProps;
12755
12805
  newProps = this.mergeAnimatedNativePropsForReact(newProps);
12806
+ if (this.fabricNativeProps) {
12807
+ newProps = mergeFabricRawProps(newProps, this.fabricNativeProps);
12808
+ }
12756
12809
  }
12757
12810
  const oldProps = this.props;
12758
12811
  const oldStyleInput = oldProps.style;
@@ -12832,7 +12885,7 @@ var SootSimNode = class _SootSimNode {
12832
12885
  if (scrollContentOffsetChanged) {
12833
12886
  const nextOffset = readContentOffsetProp(newProps.contentOffset);
12834
12887
  if (nextOffset) {
12835
- moved = this.__scroll?.scrollToOffset?.({
12888
+ moved = this.__scroll?.shiftScrollTo?.(nextOffset) === true || this.__scroll?.scrollToOffset?.({
12836
12889
  ...nextOffset,
12837
12890
  animated: false,
12838
12891
  fireScroll: true,
@@ -15291,6 +15344,7 @@ onDeviceSpecChange(_updateExports);
15291
15344
  var DEFAULT_AUX_SHELL_SCENE = {
15292
15345
  state: "home",
15293
15346
  activeAppId: null,
15347
+ systemAlertAppId: null,
15294
15348
  prewarmAppId: null,
15295
15349
  showSwitcher: false,
15296
15350
  isLocked: false,
@@ -15327,6 +15381,7 @@ var DEFAULT_AUX_SHELL_SCENE = {
15327
15381
  recentApps: []
15328
15382
  };
15329
15383
  var currentScene = DEFAULT_AUX_SHELL_SCENE;
15384
+ var systemAlertAppId = createSignal(null);
15330
15385
  function readAuxShellScene() {
15331
15386
  return currentScene;
15332
15387
  }
@@ -15440,7 +15495,7 @@ var pendingActionSheets = /* @__PURE__ */ new Map();
15440
15495
  var pendingAndroidPermissions = /* @__PURE__ */ new Map();
15441
15496
  var pendingShareSheets = /* @__PURE__ */ new Map();
15442
15497
  var nextRequestId = 1;
15443
- function showAlert(title, message, buttons, onDismiss, options, prompt, traitScheme) {
15498
+ function showAlert(title, message, buttons, onDismiss, options, prompt, traitScheme, systemPresentation) {
15444
15499
  const config = {
15445
15500
  title,
15446
15501
  message,
@@ -15462,7 +15517,8 @@ function showAlert(title, message, buttons, onDismiss, options, prompt, traitSch
15462
15517
  })),
15463
15518
  prompt
15464
15519
  };
15465
- if (!postTenantNativeUIRequest({ kind: "alert.show", requestId, spec, traitScheme })) {
15520
+ const request = systemPresentation ? { kind: "systemAlert.show", requestId, spec, ...systemPresentation } : { kind: "alert.show", requestId, spec, traitScheme };
15521
+ if (!postTenantNativeUIRequest(request)) {
15466
15522
  handleAlertResult(requestId, null);
15467
15523
  }
15468
15524
  return requestId;
@@ -15724,15 +15780,6 @@ function createToastAndroidNativeModule(toastAndroid) {
15724
15780
  };
15725
15781
  }
15726
15782
 
15727
- // ../peach-engine/src/react-native/source-code-native-module.ts
15728
- var SourceCodeNativeModule = {
15729
- getConstants: () => {
15730
- const g = globalThis;
15731
- const scriptURL = g.__sootsim_bundle_url || (g.__sootsim_bundle_origin ? `${g.__sootsim_bundle_origin}/index.bundle` : "http://localhost:8081/index.bundle");
15732
- return { scriptURL };
15733
- }
15734
- };
15735
-
15736
15783
  // ../peach-engine/src/react-native/AppState.ts
15737
15784
  var currentState = "active";
15738
15785
  var AppStateNativeModule = {
@@ -16054,6 +16101,15 @@ var Settings = {
16054
16101
  }
16055
16102
  };
16056
16103
 
16104
+ // ../peach-engine/src/react-native/source-code-native-module.ts
16105
+ var SourceCodeNativeModule = {
16106
+ getConstants: () => {
16107
+ const g = globalThis;
16108
+ const scriptURL = g.__sootsim_bundle_url || (g.__sootsim_bundle_origin ? `${g.__sootsim_bundle_origin}/index.bundle` : "http://localhost:8081/index.bundle");
16109
+ return { scriptURL };
16110
+ }
16111
+ };
16112
+
16057
16113
  // ../peach-engine/src/components/Text.tsx
16058
16114
  var import_react8 = require("react");
16059
16115
  function Text(props) {
@@ -17335,10 +17391,7 @@ function PressableInner(props, ref) {
17335
17391
  onLongPress,
17336
17392
  onInteractionFinished,
17337
17393
  minPressDuration,
17338
- onPress: props.testID === "signInButton" ? ((e) => {
17339
- console.log("[probe-press] signInButton onPress fired");
17340
- onPress?.(e);
17341
- }) : onPress,
17394
+ onPress,
17342
17395
  onPressIn(event) {
17343
17396
  if (shouldUpdatePressed) {
17344
17397
  setPressed(true);
@@ -17377,7 +17430,6 @@ function PressableInner(props, ref) {
17377
17430
  onPressMove,
17378
17431
  onPressOut,
17379
17432
  pressRetentionOffset,
17380
- props.testID,
17381
17433
  releaseRipple,
17382
17434
  shouldUpdatePressed,
17383
17435
  startRipple,
@@ -17432,23 +17484,37 @@ Pressable.displayName = "Pressable";
17432
17484
  var import_react17 = require("react");
17433
17485
 
17434
17486
  // ../peach-engine/src/components/touchable-core.ts
17435
- function buildTouchableViewProps(props, ref, wrapped) {
17487
+ function useTouchablePressability(props, wrapped) {
17488
+ return usePressability_default({
17489
+ cancelable: !props.rejectResponderTermination,
17490
+ disabled: props.disabled,
17491
+ hitSlop: props.hitSlop,
17492
+ delayLongPress: props.delayLongPress,
17493
+ delayPressIn: props.delayPressIn,
17494
+ delayPressOut: props.delayPressOut,
17495
+ minPressDuration: 0,
17496
+ pressRectOffset: props.pressRetentionOffset,
17497
+ onLongPress: props.onLongPress,
17498
+ onPress: wrapped.onPress ?? props.onPress,
17499
+ onPressIn: wrapped.onPressIn,
17500
+ onPressOut: wrapped.onPressOut
17501
+ });
17502
+ }
17503
+ function buildTouchableViewProps(props, ref) {
17436
17504
  const {
17437
17505
  // destructured only to transform or drop them; `rest` carries everything
17438
- // else (delays, hitSlop, onLayout, focusable, TV focus props, a11y props,
17439
- // etc.) straight through to the underlying view.
17506
+ // else (hitSlop, onLayout, focusable, TV focus props, a11y props, etc.)
17507
+ // straight through to the underlying view.
17440
17508
  children: _children,
17441
17509
  disabled = false,
17442
- onPress,
17443
- onPressIn: _userPressIn,
17444
- onPressOut: _userPressOut,
17445
- onLongPress,
17510
+ onPress: _onPress,
17511
+ onPressIn: _onPressIn,
17512
+ onPressOut: _onPressOut,
17513
+ onLongPress: _onLongPress,
17446
17514
  accessibilityRole,
17447
17515
  accessibilityState,
17448
17516
  id,
17449
17517
  nativeID,
17450
- // RN-specific knobs that sootsim doesn't wire — keep the names so
17451
- // component authors don't see a typed regression, but don't forward.
17452
17518
  rejectResponderTermination: _rejectResponderTermination,
17453
17519
  touchSoundDisabled: _touchSoundDisabled,
17454
17520
  ...rest
@@ -17456,10 +17522,6 @@ function buildTouchableViewProps(props, ref, wrapped) {
17456
17522
  return {
17457
17523
  ...rest,
17458
17524
  ref,
17459
- onPress: disabled ? void 0 : onPress,
17460
- onPressIn: disabled ? void 0 : wrapped.onPressIn,
17461
- onPressOut: disabled ? void 0 : wrapped.onPressOut,
17462
- onLongPress: disabled ? void 0 : onLongPress,
17463
17525
  id,
17464
17526
  nativeID: nativeID ?? id,
17465
17527
  accessibilityRole: accessibilityRole ?? "button",
@@ -17540,11 +17602,16 @@ function TouchableOpacityInner(props, ref) {
17540
17602
  animationRef.current?.stop();
17541
17603
  };
17542
17604
  }, []);
17543
- const viewProps = buildTouchableViewProps(props, ref, {
17605
+ const viewProps = buildTouchableViewProps(props, ref);
17606
+ const eventHandlers = useTouchablePressability(props, {
17544
17607
  onPressIn: handlePressIn,
17545
17608
  onPressOut: handlePressOut
17546
17609
  });
17547
- return (0, import_react17.createElement)("sootsim-view", { ...viewProps, style: animatedStyle }, children);
17610
+ return (0, import_react17.createElement)(
17611
+ "sootsim-view",
17612
+ { ...viewProps, ...eventHandlers, style: animatedStyle },
17613
+ children
17614
+ );
17548
17615
  }
17549
17616
  var TouchableOpacity = (0, import_react17.forwardRef)(TouchableOpacityInner);
17550
17617
  TouchableOpacity.displayName = "TouchableOpacity";
@@ -20922,8 +20989,24 @@ var TextInput = (0, import_react21.forwardRef)(function TextInput2(props, ref) {
20922
20989
  placeholderTextColor = DEFAULT_TEXT_INPUT_PLACEHOLDER_COLOR,
20923
20990
  onContentSizeChange,
20924
20991
  clearButtonMode = "never",
20992
+ onPress,
20993
+ onPressIn,
20994
+ onPressOut,
20995
+ rejectResponderTermination = true,
20925
20996
  ...rest
20926
20997
  } = props;
20998
+ const isAndroid = getRuntimePlatformAdapter(currentRuntimePlatform()).isAndroid;
20999
+ const pressabilityConfig = (0, import_react21.useMemo)(
21000
+ () => ({
21001
+ cancelable: isAndroid ? null : !rejectResponderTermination,
21002
+ hitSlop: rest.hitSlop,
21003
+ onPress,
21004
+ onPressIn,
21005
+ onPressOut
21006
+ }),
21007
+ [isAndroid, onPress, onPressIn, onPressOut, rejectResponderTermination, rest.hitSlop]
21008
+ );
21009
+ const pressHandlers = usePressability_default(pressabilityConfig) ?? {};
20927
21010
  const nativeText = typeof text === "string" ? text : void 0;
20928
21011
  const controlledValue = value;
20929
21012
  const hostRef = (0, import_react21.useRef)(null);
@@ -20940,10 +21023,10 @@ var TextInput = (0, import_react21.forwardRef)(function TextInput2(props, ref) {
20940
21023
  const showPlaceholder = !rawDisplayText && placeholder;
20941
21024
  const isMultiline = rest.multiline === true;
20942
21025
  const [editing, setEditing] = (0, import_react21.useState)(false);
20943
- const showClearButton = !isMultiline && rawDisplayText.length > 0 && !getRuntimePlatformAdapter(currentRuntimePlatform()).isAndroid && (clearButtonMode === "always" || clearButtonMode === "while-editing" && editing || clearButtonMode === "unless-editing" && !editing);
21026
+ const showClearButton = !isMultiline && rawDisplayText.length > 0 && !isAndroid && (clearButtonMode === "always" || clearButtonMode === "while-editing" && editing || clearButtonMode === "unless-editing" && !editing);
20944
21027
  const justifyContent = isMultiline ? "flex-start" : "center";
20945
21028
  const scrollEnabledProp = rest.scrollEnabled;
20946
- const scrollsInternally = isMultiline ? scrollEnabledProp !== false : true;
21029
+ const clipsToBounds = !isMultiline || scrollEnabledProp !== false || !isAndroid;
20947
21030
  (0, import_react21.useEffect)(() => {
20948
21031
  if (isControlled) {
20949
21032
  lastControlledValueRef.current = controlledValue;
@@ -21290,14 +21373,13 @@ var TextInput = (0, import_react21.forwardRef)(function TextInput2(props, ref) {
21290
21373
  // `flexDirection: 'row'` (e.g. Mattermost's FloatingTextInput).
21291
21374
  flexDirection: "column",
21292
21375
  justifyContent,
21293
- // UITextField/UITextView always clip to their frame natively. without
21294
- // this, a long single-line value or a tall multiline value paints
21295
- // outside the input border and the caret floats in no-mans-land.
21296
- // scrollEnabled=false multiline grows to fit content (no overflow),
21297
- // so the clip becomes a no-op rather than a behavior change.
21298
- ...scrollsInternally ? { overflow: "hidden" } : null
21376
+ // without this, a long single-line value or a tall multiline value
21377
+ // paints outside the input border and the caret floats in
21378
+ // no-mans-land.
21379
+ ...clipsToBounds ? { overflow: "hidden" } : null
21299
21380
  },
21300
21381
  ...rest,
21382
+ ...pressHandlers,
21301
21383
  ...onContentSizeChange ? { onLayout: handleHostLayout } : null,
21302
21384
  onFocus: handleFocus,
21303
21385
  onBlur: handleBlur,
@@ -23100,7 +23182,6 @@ var {
23100
23182
  thumbMargin: THUMB_MARGIN
23101
23183
  } = IOS_SWITCH_METRICS;
23102
23184
  var ON_POS = TRACK_WIDTH - IOS_THUMB_WIDTH - THUMB_MARGIN;
23103
- var LIFT_MIN_MS = 14 * 1e3 / 60;
23104
23185
  var THUMB_LAYER = {
23105
23186
  position: "absolute",
23106
23187
  left: 0,
@@ -23561,6 +23642,7 @@ function TouchableHighlightInner(props, ref) {
23561
23642
  onHideUnderlay,
23562
23643
  onPressIn,
23563
23644
  onPressOut,
23645
+ onPress,
23564
23646
  delayPressOut,
23565
23647
  style,
23566
23648
  children
@@ -23619,31 +23701,40 @@ function TouchableHighlightInner(props, ref) {
23619
23701
  );
23620
23702
  const handlePressOut = (0, import_react36.useCallback)(
23621
23703
  (e) => {
23622
- const delay = typeof delayPressOut === "number" ? delayPressOut : 0;
23704
+ if (hideTimerRef.current === null) hide();
23705
+ onPressOut?.(e);
23706
+ },
23707
+ [hide, onPressOut]
23708
+ );
23709
+ const handlePress = (0, import_react36.useCallback)(
23710
+ (e) => {
23623
23711
  clearHideTimer();
23624
- if (delay > 0) {
23625
- hideTimerRef.current = setTimeout(() => {
23626
- hideTimerRef.current = null;
23627
- hide();
23628
- }, delay);
23629
- } else {
23712
+ show();
23713
+ hideTimerRef.current = setTimeout(() => {
23714
+ hideTimerRef.current = null;
23630
23715
  hide();
23631
- }
23632
- onPressOut?.(e);
23716
+ }, delayPressOut ?? 0);
23717
+ onPress?.(e);
23633
23718
  },
23634
- [clearHideTimer, delayPressOut, hide, onPressOut]
23719
+ [clearHideTimer, delayPressOut, hide, onPress, show]
23635
23720
  );
23636
23721
  (0, import_react36.useEffect)(() => {
23637
23722
  return () => clearHideTimer();
23638
23723
  }, [clearHideTimer]);
23639
- const viewProps = buildTouchableViewProps(props, ref, {
23724
+ const viewProps = buildTouchableViewProps(props, ref);
23725
+ const eventHandlers = useTouchablePressability(props, {
23726
+ onPress: handlePress,
23640
23727
  onPressIn: handlePressIn,
23641
23728
  onPressOut: handlePressOut
23642
23729
  });
23643
23730
  const renderedChild = (0, import_react36.isValidElement)(child) ? (0, import_react36.cloneElement)(child, {
23644
23731
  style: [child.props?.style, childOpacityOverlay]
23645
23732
  }) : child;
23646
- return (0, import_react36.createElement)("sootsim-view", { ...viewProps, style: outerStyle }, renderedChild);
23733
+ return (0, import_react36.createElement)(
23734
+ "sootsim-view",
23735
+ { ...viewProps, ...eventHandlers, style: outerStyle },
23736
+ renderedChild
23737
+ );
23647
23738
  }
23648
23739
  var TouchableHighlight = (0, import_react36.forwardRef)(TouchableHighlightInner);
23649
23740
  TouchableHighlight.displayName = "TouchableHighlight";
@@ -25560,7 +25651,7 @@ function canOpenTenantUrl(url) {
25560
25651
  }
25561
25652
  function openSettings() {
25562
25653
  const open = (0, engine_config_exports.getOptionalEngineConfig)()?.nativePermissions?.openSettings;
25563
- return open ? open() : Promise.reject(
25654
+ return open ? open({ kind: "app" }) : Promise.reject(
25564
25655
  new Error(
25565
25656
  "[sootsim] app settings are unavailable before the native bridge installs"
25566
25657
  )
@@ -27175,7 +27266,8 @@ var VerticalBarColumnRegistryContext = (0, import_react44.createContext)(
27175
27266
  var VerticalBarSceneFocusContext = (0, import_react44.createContext)(true);
27176
27267
  var VerticalBarColumnMetricsContext = (0, import_react44.createContext)({
27177
27268
  availableHeaderHeight: null,
27178
- availableToolbarHeight: null
27269
+ availableToolbarHeight: null,
27270
+ availableTopToolbarHeight: null
27179
27271
  });
27180
27272
  var SPLIT_COLUMN_CHROME_KEY = "__peachSplitColumnChromeContext";
27181
27273
  var splitColumnChromeGlobals = globalThis;
@@ -27198,6 +27290,7 @@ var import_react46 = require("react");
27198
27290
  // ../peach-engine/src/components/SegmentedControl.tsx
27199
27291
  var import_react47 = require("react");
27200
27292
  var SYSTEM_TEXT = dynamicColor("#000000", "#ffffff");
27293
+ var STRETCH_GAIN = 1.87 / 60;
27201
27294
 
27202
27295
  // ../peach-compat/src/stubs/blur-utils.ts
27203
27296
  var import_react48 = require("react");
@@ -29625,6 +29718,7 @@ var NODE_COMPONENTS = {
29625
29718
  StyledToggle: import_ui.ZStack,
29626
29719
  SwipeActions: import_ui.SwipeActions,
29627
29720
  Text: import_ui.Text,
29721
+ TextEditor: import_ui.TextField,
29628
29722
  TextField: import_ui.TextField,
29629
29723
  Toggle: import_ui.Toggle,
29630
29724
  Tab: SwiftTabScene,
@@ -30187,6 +30281,9 @@ function nodeProps(node, deliver) {
30187
30281
  );
30188
30282
  return {
30189
30283
  ...align === void 0 ? {} : { style: align },
30284
+ // a vertical field grows with its lines and wraps a long one instead
30285
+ // of scrolling a single line (textfieldaxis, ios 27)
30286
+ ...props.axis === "vertical" ? { axis: "vertical" } : {},
30190
30287
  // a prompt is what the empty field shows, in the title's place; the
30191
30288
  // title still names the field (ios 27 controls oracle: SecureField
30192
30289
  // "Code" with prompt "6 digits" reads 6 digits)
@@ -30207,6 +30304,34 @@ function nodeProps(node, deliver) {
30207
30304
  ...focusProps(node, deliver)
30208
30305
  };
30209
30306
  }
30307
+ case "TextEditor": {
30308
+ const onChangeText = handlerId(node, "onChangeText");
30309
+ return {
30310
+ axis: "vertical",
30311
+ scrollEnabled: props.scrollEnabled !== false,
30312
+ // the tree's text-field control: describe collapses the engine input
30313
+ // host, so the role rides on the node describe keeps, as a
30314
+ // TextField's does
30315
+ accessibilityRole: "text-field",
30316
+ // a UITextView fills its offer on both axes and insets its text 8pt
30317
+ // from the top and bottom and 5pt from the sides, and its lines are
30318
+ // body lines (texteditor, ios 27: an empty editor in a padded stack
30319
+ // spans 370 and the rest of the height; text ink starts 5.33pt in and
30320
+ // 11.67pt down, and lines are 22pt apart)
30321
+ style: {
30322
+ lineHeight: textStyleAt("large", "body").lineHeight,
30323
+ flex: 1,
30324
+ alignSelf: "stretch",
30325
+ paddingTop: 8,
30326
+ paddingBottom: 8,
30327
+ paddingHorizontal: 5,
30328
+ textAlignVertical: "top"
30329
+ },
30330
+ ...typeof props.value === "string" ? { value: props.value } : {},
30331
+ ...onChangeText === void 0 ? {} : { onChangeText: (value) => deliver(onChangeText, value) },
30332
+ ...focusProps(node, deliver)
30333
+ };
30334
+ }
30210
30335
  case "Slider": {
30211
30336
  const onValueChange = handlerId(node, "onValueChange");
30212
30337
  return {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.629 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.630 | (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;