sootsim 0.1.238 → 0.1.240

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 (144) hide show
  1. package/dist-cli/bin.js +4 -4
  2. package/dist-cli/chunks/{agent-VQVLJBBZ.js → agent-YS355M7O.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-ABFE7KJQ.js → agent-wrapper-DJJH2DE5.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-ODI2DJ7C.js → app-fonts-2KURCNO7.js} +2 -2
  5. package/dist-cli/chunks/{assert-ZXNN3U2C.js → assert-Y7SV6LAY.js} +2 -2
  6. package/dist-cli/chunks/{auth-LMHWH6T3.js → auth-5VMBSD6F.js} +2 -2
  7. package/dist-cli/chunks/beta-KMI4GCCN.js +2 -0
  8. package/dist-cli/chunks/{camera-VWTIE3VW.js → camera-WCQNMZRH.js} +2 -2
  9. package/dist-cli/chunks/{chunk-EGRRMDLA.js → chunk-2QILUPQJ.js} +1 -1
  10. package/dist-cli/chunks/{chunk-D5LYVGSE.js → chunk-2ZEVD46I.js} +3 -3
  11. package/dist-cli/chunks/{chunk-XUOCSWW4.js → chunk-3RYTIG4Y.js} +1 -1
  12. package/dist-cli/chunks/{chunk-XWGGIFDB.js → chunk-3ULI43M6.js} +16 -8
  13. package/dist-cli/chunks/{chunk-CDAMSEOW.js → chunk-4F63QBYN.js} +3 -3
  14. package/dist-cli/chunks/{chunk-6UMCNLKY.js → chunk-4FUKKXDQ.js} +2 -2
  15. package/dist-cli/chunks/{chunk-SCLKEUCN.js → chunk-5LCZXDDX.js} +1 -1
  16. package/dist-cli/chunks/{chunk-2PFG3UHP.js → chunk-6XHVSTMH.js} +2 -2
  17. package/dist-cli/chunks/{chunk-MT2HMCDI.js → chunk-7ZTOWAQF.js} +2 -2
  18. package/dist-cli/chunks/{chunk-6PYVHZVH.js → chunk-AX56F2Z5.js} +1 -1
  19. package/dist-cli/chunks/{chunk-IHEPAACR.js → chunk-BWR3AJZ3.js} +1 -1
  20. package/dist-cli/chunks/{chunk-2FFZXFDY.js → chunk-C4MSUAGM.js} +1 -1
  21. package/dist-cli/chunks/{chunk-LYSW5PTM.js → chunk-DEO54ZY3.js} +2 -2
  22. package/dist-cli/chunks/{chunk-HTTHCQQS.js → chunk-DQEI7LOC.js} +3 -3
  23. package/dist-cli/chunks/{chunk-HC6JXVIP.js → chunk-EJ6ULQFO.js} +2 -2
  24. package/dist-cli/chunks/{chunk-MD5GBDM4.js → chunk-GI36DI2I.js} +1 -1
  25. package/dist-cli/chunks/{chunk-6KMMJDSE.js → chunk-GW7REFUB.js} +1 -1
  26. package/dist-cli/chunks/{chunk-XOKMWX3P.js → chunk-GYWIGJB7.js} +2 -2
  27. package/dist-cli/chunks/{chunk-CXV3CSSF.js → chunk-H6GS5C4F.js} +2 -2
  28. package/dist-cli/chunks/{chunk-UYFE2VRP.js → chunk-HIFBYPJK.js} +2 -2
  29. package/dist-cli/chunks/{chunk-CU7M5IBW.js → chunk-ILU6JNUJ.js} +1 -1
  30. package/dist-cli/chunks/{chunk-5MQZW32V.js → chunk-JDRG4T3G.js} +2 -2
  31. package/dist-cli/chunks/{chunk-ECCUSCHO.js → chunk-KENWUOKC.js} +2 -2
  32. package/dist-cli/chunks/{chunk-7OQU5M3J.js → chunk-KY2HHVDG.js} +2 -2
  33. package/dist-cli/chunks/{chunk-OHLPCYOM.js → chunk-LBOSTYWQ.js} +1 -1
  34. package/dist-cli/chunks/{chunk-4DN5YMPS.js → chunk-M2MJXMTO.js} +1 -1
  35. package/dist-cli/chunks/{chunk-QGCNRLCM.js → chunk-M2OTE66X.js} +2 -2
  36. package/dist-cli/chunks/{chunk-5MFTB3S4.js → chunk-M3VY5LEN.js} +1 -1
  37. package/dist-cli/chunks/{chunk-NCJGR7VZ.js → chunk-NJYDI627.js} +1 -1
  38. package/dist-cli/chunks/{chunk-YK4NG4BL.js → chunk-OBQJXFV3.js} +1 -1
  39. package/dist-cli/chunks/{chunk-GI4YPHU6.js → chunk-OKHNWLZ7.js} +2 -2
  40. package/dist-cli/chunks/{chunk-CGQTOBHQ.js → chunk-OUW757HM.js} +128 -87
  41. package/dist-cli/chunks/chunk-R54EGANH.js +1 -0
  42. package/dist-cli/chunks/{chunk-54XALXOI.js → chunk-SFNTUDIP.js} +2 -2
  43. package/dist-cli/chunks/{chunk-KGAN3JXK.js → chunk-SW5HPJC7.js} +2 -2
  44. package/dist-cli/chunks/{chunk-YNSDDYLM.js → chunk-T7BLBFPG.js} +2 -2
  45. package/dist-cli/chunks/{chunk-3KVQ35TN.js → chunk-TFXCEOCW.js} +1 -1
  46. package/dist-cli/chunks/chunk-U3VMQUN6.js +1 -0
  47. package/dist-cli/chunks/{chunk-RTMLR7KA.js → chunk-VU5WTUZJ.js} +2 -2
  48. package/dist-cli/chunks/{chunk-DMSG7ESJ.js → chunk-WYT6JDAV.js} +1 -1
  49. package/dist-cli/chunks/{chunk-A46S76WN.js → chunk-XSSTKHK7.js} +2 -2
  50. package/dist-cli/chunks/{chunk-4DPHH2DS.js → chunk-XV4VXQDA.js} +2 -2
  51. package/dist-cli/chunks/{chunk-VTY35NKD.js → chunk-XVE2O2IR.js} +2 -2
  52. package/dist-cli/chunks/{chunk-QGFPGXNJ.js → chunk-ZYMOUSJC.js} +1 -1
  53. package/dist-cli/chunks/cli-version-2BXTYTLJ.js +2 -0
  54. package/dist-cli/chunks/{compat-JZPFXICF.js → compat-LUERFKMW.js} +3 -3
  55. package/dist-cli/chunks/{config-UL7HLQDC.js → config-U4Z6TYT6.js} +2 -2
  56. package/dist-cli/chunks/{control-QKU5C5S2.js → control-I5YB63IZ.js} +2 -2
  57. package/dist-cli/chunks/daemon-VTG3XKWA.js +2 -0
  58. package/dist-cli/chunks/{debug-H5DH3AQF.js → debug-HXECWDLV.js} +3 -3
  59. package/dist-cli/chunks/{desktop-6KNJHXC3.js → desktop-NZJLDJIO.js} +3 -3
  60. package/dist-cli/chunks/{detox-GGHGQ4ZT.js → detox-LUOT4TIA.js} +2 -2
  61. package/dist-cli/chunks/{device-BRDNCJVC.js → device-7TZ7BD36.js} +2 -2
  62. package/dist-cli/chunks/{diagnose-YYUH2HKW.js → diagnose-DW2ANEGF.js} +2 -2
  63. package/dist-cli/chunks/drivers-RDXY5SDO.js +2 -0
  64. package/dist-cli/chunks/{film-ZCOJKWH3.js → film-6MYMKZ3N.js} +3 -3
  65. package/dist-cli/chunks/flow-KS77CBEA.js +2 -0
  66. package/dist-cli/chunks/help-H3ZD3LVG.js +2 -0
  67. package/dist-cli/chunks/{hidden-runtime-alias-FKPQZHNW.js → hidden-runtime-alias-FUDVEMFB.js} +2 -2
  68. package/dist-cli/chunks/{home-paths-XVONOHWM.js → home-paths-KU4MY22X.js} +2 -2
  69. package/dist-cli/chunks/inspect-ACDDO276.js +2 -0
  70. package/dist-cli/chunks/install-desktop-UQVXJAXS.js +2 -0
  71. package/dist-cli/chunks/{login-4DXNKRVF.js → login-EVS4SZQN.js} +4 -4
  72. package/dist-cli/chunks/{logout-ARENLQQ5.js → logout-K5MLSAWM.js} +2 -2
  73. package/dist-cli/chunks/{maestro-G7VNKI32.js → maestro-OEDT2T7V.js} +3 -3
  74. package/dist-cli/chunks/{maestro-generate-U3YRKKPN.js → maestro-generate-T4RZSVSM.js} +3 -3
  75. package/dist-cli/chunks/{mode-FNLKDZKM.js → mode-TZU7JML2.js} +2 -2
  76. package/dist-cli/chunks/optional-demo-registry-NIJ3MA5N.js +2 -0
  77. package/dist-cli/chunks/{perf-C3O4QGRB.js → perf-YNBU57WH.js} +2 -2
  78. package/dist-cli/chunks/{record-YEOZEOTK.js → record-V6T2INPF.js} +3 -3
  79. package/dist-cli/chunks/runtime-7XBSKGNO.js +2 -0
  80. package/dist-cli/chunks/{screenshot-command-CCVMBNZ7.js → screenshot-command-CZZ6IXSD.js} +3 -3
  81. package/dist-cli/chunks/{screenshots-capture-GIVPWSQG.js → screenshots-capture-WVR5FCHX.js} +2 -2
  82. package/dist-cli/chunks/serve-6I35UUFI.js +41 -0
  83. package/dist-cli/chunks/{setup-OQ7EMGIY.js → setup-O7GD6GME.js} +3 -3
  84. package/dist-cli/chunks/{skills-Z25AHTRM.js → skills-GBTBS2OK.js} +2 -2
  85. package/dist-cli/chunks/{storage-EDYGSOMU.js → storage-FI2YOPQE.js} +2 -2
  86. package/dist-cli/chunks/store-FU7T5NPV.js +2 -0
  87. package/dist-cli/chunks/telemetry-REPVX6LA.js +2 -0
  88. package/dist-cli/chunks/{timeline-FTAZATIZ.js → timeline-E5DVVATK.js} +2 -2
  89. package/dist-cli/chunks/{upgrade-JBRL4AHX.js → upgrade-QKOI3Q4U.js} +2 -2
  90. package/dist-cli/chunks/upload-IFQM3FG4.js +2 -0
  91. package/dist-cli/chunks/{version-H6PRWWUE.js → version-UANAPNZM.js} +2 -2
  92. package/dist-cli/chunks/web-4LZ7DUUS.js +2 -0
  93. package/dist-cli/chunks/{what-happened-A7IDSBXP.js → what-happened-JOLNICMX.js} +2 -2
  94. package/dist-lib/agent-daemon-client.cjs +1 -1
  95. package/dist-lib/agent-events.cjs +1 -1
  96. package/dist-lib/agent-identity.cjs +1 -1
  97. package/dist-lib/agent-sessions.cjs +1 -1
  98. package/dist-lib/attached-projects.cjs +1 -1
  99. package/dist-lib/auth/shared-session.cjs +1 -1
  100. package/dist-lib/backend-origin.cjs +1 -1
  101. package/dist-lib/beta.cjs +1 -1
  102. package/dist-lib/beta.mjs +1 -1
  103. package/dist-lib/bridge-constants.cjs +1 -1
  104. package/dist-lib/cli-constants.cjs +1 -1
  105. package/dist-lib/config.cjs +1 -1
  106. package/dist-lib/detox/index.cjs +1 -1
  107. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  108. package/dist-lib/home-paths.cjs +1 -1
  109. package/dist-lib/host/bridge-host.cjs +77 -33
  110. package/dist-lib/host/fetch-proxy-handler.cjs +77 -33
  111. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  112. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  113. package/dist-lib/host/websocket-proxy.cjs +1 -1
  114. package/dist-lib/index.cjs +1 -1
  115. package/dist-lib/jump-to-source-babel.cjs +1 -1
  116. package/dist-lib/menu.cjs +1 -1
  117. package/dist-lib/menu.mjs +1 -1
  118. package/dist-lib/metro.cjs +1 -1
  119. package/dist-lib/profiles.cjs +1 -1
  120. package/dist-lib/render-mode.cjs +1 -1
  121. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  122. package/dist-lib/sdk.cjs +91 -4
  123. package/dist-lib/sdk.mjs +91 -4
  124. package/dist-lib/skills.cjs +105 -40
  125. package/dist-lib/vite.cjs +1 -1
  126. package/package.json +1 -1
  127. package/src/host/fetch-proxy-handler.ts +104 -52
  128. package/dist-cli/chunks/beta-TN34R6YC.js +0 -2
  129. package/dist-cli/chunks/chunk-QAKSIRZO.js +0 -1
  130. package/dist-cli/chunks/chunk-UV4NF53M.js +0 -1
  131. package/dist-cli/chunks/cli-version-JMIF5EGD.js +0 -2
  132. package/dist-cli/chunks/daemon-IREYS2N7.js +0 -2
  133. package/dist-cli/chunks/drivers-IHDBZZUB.js +0 -2
  134. package/dist-cli/chunks/flow-TXWXTHAY.js +0 -2
  135. package/dist-cli/chunks/help-TAORLP73.js +0 -2
  136. package/dist-cli/chunks/inspect-ALJUDST3.js +0 -2
  137. package/dist-cli/chunks/install-desktop-W5JGGPCV.js +0 -2
  138. package/dist-cli/chunks/optional-demo-registry-Y5KQWQ6V.js +0 -2
  139. package/dist-cli/chunks/runtime-VCWHZCYU.js +0 -2
  140. package/dist-cli/chunks/serve-KYU7THWX.js +0 -41
  141. package/dist-cli/chunks/store-BP3EICTQ.js +0 -2
  142. package/dist-cli/chunks/telemetry-K2S6RLSW.js +0 -2
  143. package/dist-cli/chunks/upload-JVFQZS5Z.js +0 -2
  144. package/dist-cli/chunks/web-D45A6FKK.js +0 -2
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{C as N,D as F,F as y,Q as T,R as b,S}from"./chunk-XWGGIFDB.js";import{g as A,i as _}from"./chunk-CXV3CSSF.js";import"./chunk-6PYVHZVH.js";import{c as k}from"./chunk-NCJGR7VZ.js";import"./chunk-DMSG7ESJ.js";import"./chunk-YK4NG4BL.js";function O(n){let t=[];for(let e=0;e<n.length;e++)if(n[e]==="--since"&&e+1<n.length){t.push(e,e+1);let s=n[e+1].trim(),l=/^(\d+(?:\.\d+)?)(ms|s|m)?$/.exec(s);if(l){let r=Number(l[1]),u=l[2]??"ms",v=u==="s"?r*1e3:u==="m"?r*6e4:r;return{since:Date.now()-v,consumed:t}}let i=Number(s);if(Number.isFinite(i)&&i>1e12)return{since:i,consumed:t}}return{consumed:t}}function B(n){let t=[];for(let e=0;e<n.length;e++)if(n[e]==="--kinds"&&e+1<n.length)return t.push(e,e+1),{kinds:n[e+1].split(",").map(s=>s.trim()).filter(Boolean),consumed:t};return{consumed:t}}function D(n){let t=[];for(let e=0;e<n.length;e++)if(n[e]==="--limit"&&e+1<n.length){t.push(e,e+1);let s=Number(n[e+1]);if(Number.isFinite(s)&&s>0)return{limit:s,consumed:t}}return{consumed:t}}function x(n){let t=[],e={label:"initial state",events:[],startedAt:n[0]?.t??null};t.push(e);for(let s of n)if(e.events.push(s),s.kind==="screen"||s.kind==="route"){let l=s.data,i=l?.phase;if(!i||i==="enter"||i==="appear"||i==="active"){let r=l?.name||l?.activeName||l?.path||l?.pathname||s.kind;t.length===1&&e.events.length===1?e.label=`${s.kind}: ${r}`:(e={label:`${s.kind}: ${r}`,events:[],startedAt:s.t},t.push(e))}}return t}async function J(n,t){let e=A(n,{port:t.port,stripBooleanFlags:["--summary","--all","--json","--no-advance","--help","-h","--flow","--noisy"],stripValueFlags:["--since","--kinds","--limit"]});(n.includes("--help")||n.includes("-h"))&&(console.log(`
1
+ /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{C as N,D as F,F as y,Q as T,R as b,S}from"./chunk-3ULI43M6.js";import{g as A,i as _}from"./chunk-H6GS5C4F.js";import"./chunk-AX56F2Z5.js";import{c as k}from"./chunk-NJYDI627.js";import"./chunk-WYT6JDAV.js";import"./chunk-OBQJXFV3.js";function O(n){let t=[];for(let e=0;e<n.length;e++)if(n[e]==="--since"&&e+1<n.length){t.push(e,e+1);let s=n[e+1].trim(),l=/^(\d+(?:\.\d+)?)(ms|s|m)?$/.exec(s);if(l){let r=Number(l[1]),u=l[2]??"ms",v=u==="s"?r*1e3:u==="m"?r*6e4:r;return{since:Date.now()-v,consumed:t}}let i=Number(s);if(Number.isFinite(i)&&i>1e12)return{since:i,consumed:t}}return{consumed:t}}function B(n){let t=[];for(let e=0;e<n.length;e++)if(n[e]==="--kinds"&&e+1<n.length)return t.push(e,e+1),{kinds:n[e+1].split(",").map(s=>s.trim()).filter(Boolean),consumed:t};return{consumed:t}}function D(n){let t=[];for(let e=0;e<n.length;e++)if(n[e]==="--limit"&&e+1<n.length){t.push(e,e+1);let s=Number(n[e+1]);if(Number.isFinite(s)&&s>0)return{limit:s,consumed:t}}return{consumed:t}}function x(n){let t=[],e={label:"initial state",events:[],startedAt:n[0]?.t??null};t.push(e);for(let s of n)if(e.events.push(s),s.kind==="screen"||s.kind==="route"){let l=s.data,i=l?.phase;if(!i||i==="enter"||i==="appear"||i==="active"){let r=l?.name||l?.activeName||l?.path||l?.pathname||s.kind;t.length===1&&e.events.length===1?e.label=`${s.kind}: ${r}`:(e={label:`${s.kind}: ${r}`,events:[],startedAt:s.t},t.push(e))}}return t}async function J(n,t){let e=A(n,{port:t.port,stripBooleanFlags:["--summary","--all","--json","--no-advance","--help","-h","--flow","--noisy"],stripValueFlags:["--since","--kinds","--limit"]});(n.includes("--help")||n.includes("-h"))&&(console.log(`
3
3
  sootsim what-happened \u2014 show recent events from the semantic timeline
4
4
 
5
5
  usage:
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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/beta.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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/beta.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/beta.ts
4
4
  var IS_BETA = true;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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;
@@ -2355,6 +2355,7 @@ function mapFrameworkToProjectFramework(fw) {
2355
2355
  // src/host/fetch-proxy-handler.ts
2356
2356
  var import_http2 = __toESM(require("http"), 1);
2357
2357
  var import_https = __toESM(require("https"), 1);
2358
+ var import_promises2 = require("stream/promises");
2358
2359
 
2359
2360
  // src/host/fetch-proxy-overrides.ts
2360
2361
  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";
@@ -2442,12 +2443,6 @@ function formatFetchProxyError(targetUrl, err) {
2442
2443
  }
2443
2444
  return message;
2444
2445
  }
2445
- function isTextProxyContentType(contentType) {
2446
- const value = Array.isArray(contentType) ? contentType[0] : contentType;
2447
- const normalized = value?.split(";", 1)[0]?.trim().toLowerCase();
2448
- if (!normalized) return false;
2449
- return normalized.startsWith("text/") || normalized === "application/json" || normalized.endsWith("+json") || normalized === "application/x-www-form-urlencoded" || normalized === "application/xml" || normalized.endsWith("+xml") || normalized === "application/javascript" || normalized === "application/graphql";
2450
- }
2451
2446
  function buildFetchProxyHeaders(reqHeaders, targetUrl) {
2452
2447
  const headers = {};
2453
2448
  for (const [key, value] of Object.entries(reqHeaders)) {
@@ -2506,7 +2501,6 @@ async function handleFetchProxyRequest(req, res) {
2506
2501
  res.end("invalid url param");
2507
2502
  return;
2508
2503
  }
2509
- const headers = buildFetchProxyHeaders(req.headers, upstreamUrl);
2510
2504
  let body;
2511
2505
  if (req.method !== "GET" && req.method !== "HEAD") {
2512
2506
  const chunks = [];
@@ -2514,39 +2508,89 @@ async function handleFetchProxyRequest(req, res) {
2514
2508
  chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
2515
2509
  }
2516
2510
  if (chunks.length > 0) {
2517
- const bytes = Buffer.concat(chunks);
2518
- body = isTextProxyContentType(req.headers["content-type"]) ? bytes.toString("utf8") : bytes;
2511
+ body = Buffer.concat(chunks);
2519
2512
  }
2520
2513
  }
2521
- let upstream;
2522
- try {
2523
- upstream = await fetch(upstreamUrl.href, {
2524
- method: req.method,
2525
- headers,
2526
- body,
2527
- redirect: "follow"
2514
+ const originalMethod = req.method || "GET";
2515
+ const proxy = async (targetUrl2, method, nextBody, redirects) => {
2516
+ const transport = targetUrl2.protocol === "https:" ? import_https.default : import_http2.default;
2517
+ const targetHeaders = buildFetchProxyHeaders(req.headers, targetUrl2);
2518
+ if (targetUrl2.origin !== upstreamUrl.origin) {
2519
+ delete targetHeaders.authorization;
2520
+ delete targetHeaders["proxy-authorization"];
2521
+ }
2522
+ if (method === "GET" || method === "HEAD") {
2523
+ delete targetHeaders["content-length"];
2524
+ delete targetHeaders["content-type"];
2525
+ } else if (nextBody) {
2526
+ targetHeaders["content-length"] = String(nextBody.byteLength);
2527
+ }
2528
+ const proxyRes = await new Promise((resolve, reject) => {
2529
+ const proxyReq = transport.request(
2530
+ {
2531
+ hostname: targetUrl2.hostname,
2532
+ port: targetUrl2.port || (targetUrl2.protocol === "https:" ? 443 : 80),
2533
+ path: targetUrl2.pathname + targetUrl2.search,
2534
+ method,
2535
+ headers: targetHeaders
2536
+ },
2537
+ resolve
2538
+ );
2539
+ const abort = () => proxyReq.destroy(new Error("fetch proxy client disconnected"));
2540
+ req.once("aborted", abort);
2541
+ proxyReq.once("close", () => req.off("aborted", abort));
2542
+ proxyReq.once("error", reject);
2543
+ if (nextBody === void 0) proxyReq.end();
2544
+ else proxyReq.end(nextBody);
2528
2545
  });
2546
+ const status = proxyRes.statusCode ?? 502;
2547
+ const location = proxyRes.headers.location;
2548
+ if (location && (status === 301 || status === 302 || status === 303 || status === 307 || status === 308)) {
2549
+ if (redirects >= 10) {
2550
+ proxyRes.destroy();
2551
+ throw new Error("too many redirects");
2552
+ }
2553
+ const switchToGet = (status === 301 || status === 302) && method === "POST" || status === 303 && method !== "GET" && method !== "HEAD";
2554
+ const redirectUrl = new URL(location, targetUrl2);
2555
+ proxyRes.resume();
2556
+ await (0, import_promises2.finished)(proxyRes);
2557
+ await proxy(
2558
+ redirectUrl,
2559
+ switchToGet ? "GET" : method,
2560
+ switchToGet ? void 0 : nextBody,
2561
+ redirects + 1
2562
+ );
2563
+ return;
2564
+ }
2565
+ for (const [key, value] of Object.entries(proxyRes.headers)) {
2566
+ const lowerKey = key.toLowerCase();
2567
+ if (value === void 0 || lowerKey === "set-cookie" || lowerKey === "connection" || lowerKey === "keep-alive" || lowerKey === "proxy-authenticate" || lowerKey === "proxy-authorization" || lowerKey === "te" || lowerKey === "trailer" || lowerKey === "transfer-encoding" || lowerKey === "upgrade" || lowerKey.startsWith("access-control-")) {
2568
+ continue;
2569
+ }
2570
+ res.setHeader(key, value);
2571
+ }
2572
+ applyFetchProxyCors(res);
2573
+ const setCookie = proxyRes.headers["set-cookie"] ?? [];
2574
+ if (setCookie.length > 0) {
2575
+ res.setHeader(
2576
+ "x-sootsim-set-cookie",
2577
+ (Array.isArray(setCookie) ? setCookie : [setCookie]).join(", ")
2578
+ );
2579
+ }
2580
+ res.statusCode = status;
2581
+ await (0, import_promises2.pipeline)(proxyRes, res);
2582
+ };
2583
+ try {
2584
+ await proxy(upstreamUrl, originalMethod, body, 0);
2529
2585
  } catch (err) {
2586
+ if (res.headersSent) {
2587
+ res.destroy(err instanceof Error ? err : new Error(String(err)));
2588
+ return;
2589
+ }
2530
2590
  applyFetchProxyCors(res);
2531
2591
  res.writeHead(502, { "Content-Type": "text/plain" });
2532
2592
  res.end(`fetch proxy error: ${formatFetchProxyError(upstreamUrl.href, err)}`);
2533
- return;
2534
2593
  }
2535
- upstream.headers.forEach((value, key) => {
2536
- const lowerKey = key.toLowerCase();
2537
- if (lowerKey === "content-encoding" || lowerKey === "transfer-encoding" || lowerKey === "content-length" || lowerKey === "set-cookie" || lowerKey.startsWith("access-control-")) {
2538
- return;
2539
- }
2540
- res.setHeader(key, value);
2541
- });
2542
- applyFetchProxyCors(res);
2543
- const setCookie = upstream.headers.getSetCookie?.() ?? [];
2544
- if (setCookie.length > 0) {
2545
- res.setHeader("x-sootsim-set-cookie", setCookie.join(", "));
2546
- }
2547
- res.statusCode = upstream.status;
2548
- const buf = Buffer.from(await upstream.arrayBuffer());
2549
- res.end(buf);
2550
2594
  }
2551
2595
  function handleAppApiRequest(req, res) {
2552
2596
  const reqUrl = req.url || "";
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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;
@@ -42,6 +42,7 @@ __export(fetch_proxy_handler_exports, {
42
42
  module.exports = __toCommonJS(fetch_proxy_handler_exports);
43
43
  var import_http = __toESM(require("http"), 1);
44
44
  var import_https = __toESM(require("https"), 1);
45
+ var import_promises = require("stream/promises");
45
46
 
46
47
  // src/host/fetch-proxy-overrides.ts
47
48
  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";
@@ -129,12 +130,6 @@ function formatFetchProxyError(targetUrl, err) {
129
130
  }
130
131
  return message;
131
132
  }
132
- function isTextProxyContentType(contentType) {
133
- const value = Array.isArray(contentType) ? contentType[0] : contentType;
134
- const normalized = value?.split(";", 1)[0]?.trim().toLowerCase();
135
- if (!normalized) return false;
136
- return normalized.startsWith("text/") || normalized === "application/json" || normalized.endsWith("+json") || normalized === "application/x-www-form-urlencoded" || normalized === "application/xml" || normalized.endsWith("+xml") || normalized === "application/javascript" || normalized === "application/graphql";
137
- }
138
133
  function buildFetchProxyHeaders(reqHeaders, targetUrl) {
139
134
  const headers = {};
140
135
  for (const [key, value] of Object.entries(reqHeaders)) {
@@ -193,7 +188,6 @@ async function handleFetchProxyRequest(req, res) {
193
188
  res.end("invalid url param");
194
189
  return;
195
190
  }
196
- const headers = buildFetchProxyHeaders(req.headers, upstreamUrl);
197
191
  let body;
198
192
  if (req.method !== "GET" && req.method !== "HEAD") {
199
193
  const chunks = [];
@@ -201,39 +195,89 @@ async function handleFetchProxyRequest(req, res) {
201
195
  chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
202
196
  }
203
197
  if (chunks.length > 0) {
204
- const bytes = Buffer.concat(chunks);
205
- body = isTextProxyContentType(req.headers["content-type"]) ? bytes.toString("utf8") : bytes;
198
+ body = Buffer.concat(chunks);
206
199
  }
207
200
  }
208
- let upstream;
209
- try {
210
- upstream = await fetch(upstreamUrl.href, {
211
- method: req.method,
212
- headers,
213
- body,
214
- redirect: "follow"
201
+ const originalMethod = req.method || "GET";
202
+ const proxy = async (targetUrl2, method, nextBody, redirects) => {
203
+ const transport = targetUrl2.protocol === "https:" ? import_https.default : import_http.default;
204
+ const targetHeaders = buildFetchProxyHeaders(req.headers, targetUrl2);
205
+ if (targetUrl2.origin !== upstreamUrl.origin) {
206
+ delete targetHeaders.authorization;
207
+ delete targetHeaders["proxy-authorization"];
208
+ }
209
+ if (method === "GET" || method === "HEAD") {
210
+ delete targetHeaders["content-length"];
211
+ delete targetHeaders["content-type"];
212
+ } else if (nextBody) {
213
+ targetHeaders["content-length"] = String(nextBody.byteLength);
214
+ }
215
+ const proxyRes = await new Promise((resolve, reject) => {
216
+ const proxyReq = transport.request(
217
+ {
218
+ hostname: targetUrl2.hostname,
219
+ port: targetUrl2.port || (targetUrl2.protocol === "https:" ? 443 : 80),
220
+ path: targetUrl2.pathname + targetUrl2.search,
221
+ method,
222
+ headers: targetHeaders
223
+ },
224
+ resolve
225
+ );
226
+ const abort = () => proxyReq.destroy(new Error("fetch proxy client disconnected"));
227
+ req.once("aborted", abort);
228
+ proxyReq.once("close", () => req.off("aborted", abort));
229
+ proxyReq.once("error", reject);
230
+ if (nextBody === void 0) proxyReq.end();
231
+ else proxyReq.end(nextBody);
215
232
  });
233
+ const status = proxyRes.statusCode ?? 502;
234
+ const location = proxyRes.headers.location;
235
+ if (location && (status === 301 || status === 302 || status === 303 || status === 307 || status === 308)) {
236
+ if (redirects >= 10) {
237
+ proxyRes.destroy();
238
+ throw new Error("too many redirects");
239
+ }
240
+ const switchToGet = (status === 301 || status === 302) && method === "POST" || status === 303 && method !== "GET" && method !== "HEAD";
241
+ const redirectUrl = new URL(location, targetUrl2);
242
+ proxyRes.resume();
243
+ await (0, import_promises.finished)(proxyRes);
244
+ await proxy(
245
+ redirectUrl,
246
+ switchToGet ? "GET" : method,
247
+ switchToGet ? void 0 : nextBody,
248
+ redirects + 1
249
+ );
250
+ return;
251
+ }
252
+ for (const [key, value] of Object.entries(proxyRes.headers)) {
253
+ const lowerKey = key.toLowerCase();
254
+ if (value === void 0 || lowerKey === "set-cookie" || lowerKey === "connection" || lowerKey === "keep-alive" || lowerKey === "proxy-authenticate" || lowerKey === "proxy-authorization" || lowerKey === "te" || lowerKey === "trailer" || lowerKey === "transfer-encoding" || lowerKey === "upgrade" || lowerKey.startsWith("access-control-")) {
255
+ continue;
256
+ }
257
+ res.setHeader(key, value);
258
+ }
259
+ applyFetchProxyCors(res);
260
+ const setCookie = proxyRes.headers["set-cookie"] ?? [];
261
+ if (setCookie.length > 0) {
262
+ res.setHeader(
263
+ "x-sootsim-set-cookie",
264
+ (Array.isArray(setCookie) ? setCookie : [setCookie]).join(", ")
265
+ );
266
+ }
267
+ res.statusCode = status;
268
+ await (0, import_promises.pipeline)(proxyRes, res);
269
+ };
270
+ try {
271
+ await proxy(upstreamUrl, originalMethod, body, 0);
216
272
  } catch (err) {
273
+ if (res.headersSent) {
274
+ res.destroy(err instanceof Error ? err : new Error(String(err)));
275
+ return;
276
+ }
217
277
  applyFetchProxyCors(res);
218
278
  res.writeHead(502, { "Content-Type": "text/plain" });
219
279
  res.end(`fetch proxy error: ${formatFetchProxyError(upstreamUrl.href, err)}`);
220
- return;
221
- }
222
- upstream.headers.forEach((value, key) => {
223
- const lowerKey = key.toLowerCase();
224
- if (lowerKey === "content-encoding" || lowerKey === "transfer-encoding" || lowerKey === "content-length" || lowerKey === "set-cookie" || lowerKey.startsWith("access-control-")) {
225
- return;
226
- }
227
- res.setHeader(key, value);
228
- });
229
- applyFetchProxyCors(res);
230
- const setCookie = upstream.headers.getSetCookie?.() ?? [];
231
- if (setCookie.length > 0) {
232
- res.setHeader("x-sootsim-set-cookie", setCookie.join(", "));
233
280
  }
234
- res.statusCode = upstream.status;
235
- const buf = Buffer.from(await upstream.arrayBuffer());
236
- res.end(buf);
237
281
  }
238
282
  function handleAppApiRequest(req, res) {
239
283
  const reqUrl = req.url || "";
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/menu.ts
4
4
  var SOOTSIM_ENGINE_EVENT_NAME = "sootsim:engine-event";
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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
- /*! sootsim v0.1.238 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.240 | (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;
@@ -340,6 +340,14 @@ function layoutGetNativeEval(opts = {}) {
340
340
  const abs = n.absolute || n.absolutePosition || { x: layout.x, y: layout.y }
341
341
  const text = typeof n.text === 'string' && n.text.trim() ? n.text.trim() : undefined
342
342
  const base = {
343
+ ...(typeof n.nodeId === 'number'
344
+ ? {
345
+ nodeId: n.nodeId,
346
+ ancestorIds: Array.isArray(n.ancestors)
347
+ ? n.ancestors.map((ancestor) => ancestor && ancestor.nodeId).filter((id) => typeof id === 'number')
348
+ : [],
349
+ }
350
+ : {}),
343
351
  testID: n.testID || n.testId || undefined,
344
352
  role: n.accessibilityRole || n.role || undefined,
345
353
  type: typeof n.type === 'string' ? n.type : 'node',
@@ -1049,7 +1057,13 @@ async function inspectScrollStateAt(bridge, x, y) {
1049
1057
  path: "__sootsimTest.getScrollStateAt",
1050
1058
  args: [x, y]
1051
1059
  });
1052
- return result && typeof result === "object" ? result : null;
1060
+ if (!result || typeof result !== "object") return null;
1061
+ const state = result;
1062
+ return {
1063
+ ...state,
1064
+ scrollOffsetX: typeof state.scrollOffsetX === "number" ? state.scrollOffsetX : state.offsetX,
1065
+ scrollOffsetY: typeof state.scrollOffsetY === "number" ? state.scrollOffsetY : state.offsetY
1066
+ };
1053
1067
  }
1054
1068
  async function inspectLogs(bridge) {
1055
1069
  const res = await bridge.send({
@@ -1559,6 +1573,7 @@ function tapTiming(agent, opts = {}) {
1559
1573
  }
1560
1574
  function isTapSuccess(result) {
1561
1575
  if (!result || result.hit === false || result.ok === false) return false;
1576
+ if (result.requestedTargetMatched === false) return false;
1562
1577
  if (result.pointerTapHandled === false && !result.keyboardOpened && !result.isTextInput) {
1563
1578
  return false;
1564
1579
  }
@@ -1566,6 +1581,7 @@ function isTapSuccess(result) {
1566
1581
  }
1567
1582
  function tapTargetFromPayload(payload, textFallback) {
1568
1583
  return {
1584
+ nodeId: payload.target?.nodeId ?? payload.match?.nodeId ?? payload.node?.nodeId ?? null,
1569
1585
  id: payload.target?.id ?? payload.match?.id ?? payload.node?.id ?? null,
1570
1586
  testID: payload.target?.testID ?? payload.match?.testID ?? payload.node?.testID ?? null,
1571
1587
  text: payload.target?.text ?? payload.target?.accessibilityLabel ?? payload.match?.text ?? payload.match?.accessibilityLabel ?? payload.node?.text ?? textFallback ?? null,
@@ -1611,12 +1627,83 @@ async function tapResolvedTarget(bridge, args) {
1611
1627
  lastOffscreenAt = at;
1612
1628
  } else {
1613
1629
  lastOffscreenAt = null;
1614
- const result = await bridge.send({
1630
+ const requestedTarget = tapTargetFromPayload(payload, args.textFallback);
1631
+ const verification = await bridge.send({
1632
+ type: "evaluate",
1633
+ code: `(async () => {
1634
+ const t = window.__sootsimTest
1635
+ if (
1636
+ !t ||
1637
+ typeof t.inspectAt !== 'function' ||
1638
+ typeof t.resolveTapTarget !== 'function'
1639
+ ) {
1640
+ return { error: 'tap-target-inspection-unavailable' }
1641
+ }
1642
+ const requestedTarget = ${JSON.stringify(requestedTarget)}
1643
+ const inspected = await t.inspectAt(${payload.cx}, ${payload.cy})
1644
+ const resolved =
1645
+ inspected && typeof inspected.nodeId === 'number'
1646
+ ? await t.resolveTapTarget(inspected.nodeId)
1647
+ : null
1648
+ const node = (resolved && resolved.target) || inspected
1649
+ const coordinateTarget = node
1650
+ ? {
1651
+ nodeId: node.nodeId ?? null,
1652
+ id: node.id ?? null,
1653
+ testID: node.testID ?? null,
1654
+ text: node.text ?? node.accessibilityLabel ?? null,
1655
+ type: node.type ?? null,
1656
+ }
1657
+ : null
1658
+ const requestedTargetMatched =
1659
+ coordinateTarget === null
1660
+ ? false
1661
+ : typeof requestedTarget.nodeId === 'number' &&
1662
+ typeof coordinateTarget.nodeId === 'number'
1663
+ ? requestedTarget.nodeId === coordinateTarget.nodeId
1664
+ : requestedTarget.testID && coordinateTarget.testID
1665
+ ? requestedTarget.testID === coordinateTarget.testID
1666
+ : requestedTarget.id && coordinateTarget.id
1667
+ ? requestedTarget.id === coordinateTarget.id
1668
+ : false
1669
+ return {
1670
+ requestedTargetMatched,
1671
+ requestedTarget,
1672
+ coordinateTarget,
1673
+ }
1674
+ })()`
1675
+ });
1676
+ if (verification?.error) {
1677
+ return {
1678
+ payload,
1679
+ result: {
1680
+ hit: false,
1681
+ reason: verification.error,
1682
+ requestedTarget
1683
+ },
1684
+ attempts,
1685
+ failure: "special"
1686
+ };
1687
+ }
1688
+ if (verification?.requestedTargetMatched === false) {
1689
+ return {
1690
+ payload,
1691
+ result: {
1692
+ hit: false,
1693
+ reason: "target-covered",
1694
+ ...verification
1695
+ },
1696
+ attempts,
1697
+ failure: "missed"
1698
+ };
1699
+ }
1700
+ const dispatched = await bridge.send({
1615
1701
  type: "tap",
1616
1702
  x: payload.cx,
1617
1703
  y: payload.cy,
1618
- target: tapTargetFromPayload(payload, args.textFallback)
1704
+ target: requestedTarget
1619
1705
  });
1706
+ const result = dispatched && typeof dispatched === "object" ? { ...dispatched, ...verification } : { hit: !!dispatched, ...verification };
1620
1707
  lastResult = result;
1621
1708
  if (isTapSuccess(result)) return { payload, result, attempts };
1622
1709
  }