sootsim 0.1.215 → 0.1.216

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 (149) hide show
  1. package/detox/index.ts +30 -16
  2. package/dist-cli/bin.js +4 -4
  3. package/dist-cli/chunks/{agent-63EE3N4N.js → agent-RMGUE35J.js} +2 -2
  4. package/dist-cli/chunks/{agent-wrapper-GIXQ4UC3.js → agent-wrapper-PNKMWDVX.js} +2 -2
  5. package/dist-cli/chunks/{app-fonts-T24PVENP.js → app-fonts-Z6SGSVKJ.js} +2 -2
  6. package/dist-cli/chunks/{assert-C2EJWQW3.js → assert-ELIDRXY7.js} +2 -2
  7. package/dist-cli/chunks/{auth-HYWSF7FV.js → auth-2NJA7QI6.js} +2 -2
  8. package/dist-cli/chunks/beta-MTYUL7U7.js +2 -0
  9. package/dist-cli/chunks/{camera-TUULMDLJ.js → camera-XICNRGGO.js} +2 -2
  10. package/dist-cli/chunks/{chunk-E6YKEDDM.js → chunk-2FNN7T63.js} +1 -1
  11. package/dist-cli/chunks/{chunk-5GU7LW64.js → chunk-4BUASWNE.js} +1 -1
  12. package/dist-cli/chunks/{chunk-UJZFS2JM.js → chunk-4XCGYTBN.js} +2 -2
  13. package/dist-cli/chunks/chunk-5LT4NR6Y.js +1 -0
  14. package/dist-cli/chunks/chunk-6KRC622O.js +1 -0
  15. package/dist-cli/chunks/{chunk-RIAS4TMS.js → chunk-6TZMBHQ5.js} +3 -3
  16. package/dist-cli/chunks/{chunk-AHG7WAP6.js → chunk-7SPHDLSB.js} +2 -2
  17. package/dist-cli/chunks/{chunk-BU7V5UGD.js → chunk-AWSL2LAA.js} +2 -2
  18. package/dist-cli/chunks/{chunk-EB4FLAAE.js → chunk-BGDEZZWT.js} +2 -2
  19. package/dist-cli/chunks/{chunk-CSJUJIRP.js → chunk-CCFLATUR.js} +2 -2
  20. package/dist-cli/chunks/{chunk-6USQVYW2.js → chunk-CQSIRKJ2.js} +2 -2
  21. package/dist-cli/chunks/{chunk-6NQYBCWC.js → chunk-CRU7UL5Q.js} +1 -1
  22. package/dist-cli/chunks/{chunk-OHQOMV2J.js → chunk-CU3LQUJD.js} +2 -2
  23. package/dist-cli/chunks/chunk-DA7KPSMF.js +2 -0
  24. package/dist-cli/chunks/{chunk-QGFTJYVC.js → chunk-DRFWZ74H.js} +1 -1
  25. package/dist-cli/chunks/{chunk-T4EGFOSE.js → chunk-G6VHJWGQ.js} +1 -1
  26. package/dist-cli/chunks/{chunk-DVJZUBQB.js → chunk-GIZDZKHC.js} +1 -1
  27. package/dist-cli/chunks/{chunk-FWUGH36K.js → chunk-GPLW7IL5.js} +2 -2
  28. package/dist-cli/chunks/{chunk-KG6V4NCI.js → chunk-HBCEGJQH.js} +2 -2
  29. package/dist-cli/chunks/chunk-HIDDRHAN.js +99 -0
  30. package/dist-cli/chunks/chunk-HKKKZRKS.js +89 -0
  31. package/dist-cli/chunks/{chunk-ZT7M27FX.js → chunk-HZCW6RRE.js} +2 -2
  32. package/dist-cli/chunks/{chunk-7COBEK2I.js → chunk-J4GDWHXE.js} +2 -2
  33. package/dist-cli/chunks/{chunk-AKNZ6QBL.js → chunk-J74AW22R.js} +1 -1
  34. package/dist-cli/chunks/{chunk-LIFR6X36.js → chunk-LWECTC6A.js} +2 -2
  35. package/dist-cli/chunks/{chunk-VD2SYCCY.js → chunk-M2DYRSIS.js} +2 -2
  36. package/dist-cli/chunks/chunk-P5JY275Q.js +119 -0
  37. package/dist-cli/chunks/{chunk-VMYBUPRT.js → chunk-P735P65P.js} +93 -65
  38. package/dist-cli/chunks/{chunk-XVYCMZMB.js → chunk-QNRORBZE.js} +2 -2
  39. package/dist-cli/chunks/{chunk-FEFLFVIU.js → chunk-RESHDGBU.js} +1 -1
  40. package/dist-cli/chunks/{chunk-RFJMDMLK.js → chunk-S3C2S27B.js} +2 -2
  41. package/dist-cli/chunks/{chunk-QXJPLKP7.js → chunk-SBP46OOV.js} +1 -1
  42. package/dist-cli/chunks/{chunk-5MUXEXEW.js → chunk-SPKRGAWR.js} +2 -2
  43. package/dist-cli/chunks/{chunk-CKCDJCPZ.js → chunk-SSLFXUZQ.js} +1 -1
  44. package/dist-cli/chunks/chunk-TNPHXSMV.js +2 -0
  45. package/dist-cli/chunks/{chunk-EGCQXWLS.js → chunk-U7UICUB4.js} +2 -2
  46. package/dist-cli/chunks/{chunk-X7VZ7D6Y.js → chunk-UGNYHNBN.js} +3 -3
  47. package/dist-cli/chunks/{chunk-2FEGONIZ.js → chunk-UPLXEL4D.js} +1 -1
  48. package/dist-cli/chunks/{chunk-EWYTZ7FV.js → chunk-URGNAE7V.js} +31 -31
  49. package/dist-cli/chunks/{chunk-HKEH2UOD.js → chunk-VDONTXCB.js} +1 -1
  50. package/dist-cli/chunks/{chunk-SADP73NH.js → chunk-VSGSEQE7.js} +2 -2
  51. package/dist-cli/chunks/{chunk-OUB7WT7Q.js → chunk-VURHG6DO.js} +1 -1
  52. package/dist-cli/chunks/{chunk-YTQ5RCVB.js → chunk-YN44PKW5.js} +1 -1
  53. package/dist-cli/chunks/cli-version-BP5GKAZ6.js +2 -0
  54. package/dist-cli/chunks/{compat-EL7PRWER.js → compat-MF7YZPCS.js} +3 -3
  55. package/dist-cli/chunks/{config-IZZQIOI5.js → config-WJSCJ622.js} +2 -2
  56. package/dist-cli/chunks/{control-FHQBCUP6.js → control-AZFQJXJ5.js} +2 -2
  57. package/dist-cli/chunks/daemon-MU77JEAP.js +2 -0
  58. package/dist-cli/chunks/{debug-6CB5QEGF.js → debug-LIXGHFHV.js} +3 -3
  59. package/dist-cli/chunks/{desktop-DLU2VTNC.js → desktop-T7GTXHL4.js} +3 -3
  60. package/dist-cli/chunks/{detox-N2D2AY7S.js → detox-WV5FD4G6.js} +2 -2
  61. package/dist-cli/chunks/{device-FGZWPD26.js → device-GPHUF3BL.js} +2 -2
  62. package/dist-cli/chunks/{diagnose-ICQE2EWG.js → diagnose-OAXHSPXW.js} +2 -2
  63. package/dist-cli/chunks/drivers-LJAA7XSZ.js +2 -0
  64. package/dist-cli/chunks/film-ZBYERRWW.js +69 -0
  65. package/dist-cli/chunks/flow-TXG46ARF.js +2 -0
  66. package/dist-cli/chunks/help-BVVLN5KL.js +2 -0
  67. package/dist-cli/chunks/{home-paths-VWN4PHJ3.js → home-paths-T3SY5QGR.js} +2 -2
  68. package/dist-cli/chunks/inspect-7SHQVCCL.js +2 -0
  69. package/dist-cli/chunks/install-desktop-RFGXCZRS.js +2 -0
  70. package/dist-cli/chunks/{login-FO2R5CSL.js → login-QS2GVTJJ.js} +4 -4
  71. package/dist-cli/chunks/{logout-L5R3GRIG.js → logout-I752SSKU.js} +2 -2
  72. package/dist-cli/chunks/{maestro-K57OH6RI.js → maestro-RDBKRP4O.js} +3 -3
  73. package/dist-cli/chunks/{maestro-generate-7VVSWXKH.js → maestro-generate-JOTQKAEH.js} +3 -3
  74. package/dist-cli/chunks/mode-Z4W3XXXU.js +24 -0
  75. package/dist-cli/chunks/optional-demo-registry-JTRVZB45.js +2 -0
  76. package/dist-cli/chunks/{perf-AA66N7ML.js → perf-RXXW5GRA.js} +2 -2
  77. package/dist-cli/chunks/{record-HVK5TWAF.js → record-527ZYKHE.js} +3 -3
  78. package/dist-cli/chunks/runtime-DOAHJLEK.js +2 -0
  79. package/dist-cli/chunks/{screenshot-command-TPVAQ6FC.js → screenshot-command-OBPEZJLR.js} +3 -3
  80. package/dist-cli/chunks/{screenshots-capture-OT5KMPQQ.js → screenshots-capture-VC752Q3V.js} +2 -2
  81. package/dist-cli/chunks/{serve-3CTBVM5S.js → serve-NU6WWN2K.js} +2 -2
  82. package/dist-cli/chunks/{setup-JCJJQJKU.js → setup-6BJWI3PC.js} +3 -3
  83. package/dist-cli/chunks/{skills-HTH527W2.js → skills-L7JPAJEZ.js} +2 -2
  84. package/dist-cli/chunks/{storage-O6RNOFWM.js → storage-XIZZSPC3.js} +2 -2
  85. package/dist-cli/chunks/store-3UAGOXD4.js +2 -0
  86. package/dist-cli/chunks/telemetry-IXCWQVEB.js +2 -0
  87. package/dist-cli/chunks/{timeline-RQHPAEK6.js → timeline-3MAGSV2V.js} +2 -2
  88. package/dist-cli/chunks/{upgrade-OKNBSSBF.js → upgrade-YDHOHVYZ.js} +2 -2
  89. package/dist-cli/chunks/upload-YQVEPIO7.js +2 -0
  90. package/dist-cli/chunks/{version-EY4PANXP.js → version-QDGDS5P2.js} +2 -2
  91. package/dist-cli/chunks/web-BK6VHH5W.js +2 -0
  92. package/dist-cli/chunks/{what-happened-MC5PTHCG.js → what-happened-4GGACNI4.js} +2 -2
  93. package/dist-lib/agent-daemon-client.cjs +1 -1
  94. package/dist-lib/agent-events.cjs +1 -1
  95. package/dist-lib/agent-identity.cjs +1 -1
  96. package/dist-lib/agent-sessions.cjs +1 -1
  97. package/dist-lib/attached-projects.cjs +1 -1
  98. package/dist-lib/auth/shared-session.cjs +1 -1
  99. package/dist-lib/backend-origin.cjs +1 -1
  100. package/dist-lib/beta.cjs +1 -1
  101. package/dist-lib/beta.mjs +1 -1
  102. package/dist-lib/bridge-constants.cjs +1 -1
  103. package/dist-lib/cli-constants.cjs +1 -1
  104. package/dist-lib/config.cjs +1 -1
  105. package/dist-lib/detox/index.cjs +108 -12
  106. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  107. package/dist-lib/home-paths.cjs +1 -1
  108. package/dist-lib/host/bridge-host.cjs +1 -1
  109. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  110. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  111. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  112. package/dist-lib/host/websocket-proxy.cjs +1 -1
  113. package/dist-lib/index.cjs +1 -1
  114. package/dist-lib/jump-to-source-babel.cjs +1 -1
  115. package/dist-lib/menu.cjs +1 -1
  116. package/dist-lib/menu.mjs +1 -1
  117. package/dist-lib/metro.cjs +1 -1
  118. package/dist-lib/profiles.cjs +1 -1
  119. package/dist-lib/render-mode.cjs +1 -1
  120. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  121. package/dist-lib/sdk.cjs +57 -9
  122. package/dist-lib/sdk.mjs +57 -9
  123. package/dist-lib/skills.cjs +22 -14
  124. package/dist-lib/vite.cjs +1 -1
  125. package/package.json +1 -1
  126. package/skills/soot/SKILL.md +1 -0
  127. package/skills/sootsim-debug/SKILL.md +6 -8
  128. package/skills/sootsim-perf/SKILL.md +4 -4
  129. package/dist-cli/chunks/beta-YMHG327W.js +0 -2
  130. package/dist-cli/chunks/chunk-A3LHGXZW.js +0 -1
  131. package/dist-cli/chunks/chunk-AHWQZXFB.js +0 -119
  132. package/dist-cli/chunks/chunk-K7OZYJKD.js +0 -2
  133. package/dist-cli/chunks/chunk-KGSLGXWW.js +0 -2
  134. package/dist-cli/chunks/chunk-NJPDAYWO.js +0 -1
  135. package/dist-cli/chunks/chunk-VIXY7DGW.js +0 -97
  136. package/dist-cli/chunks/cli-version-DPI32W6E.js +0 -2
  137. package/dist-cli/chunks/daemon-GF5QBYWN.js +0 -2
  138. package/dist-cli/chunks/drivers-J4BHBZXD.js +0 -2
  139. package/dist-cli/chunks/flow-LTUM776G.js +0 -2
  140. package/dist-cli/chunks/help-LBG75ITV.js +0 -2
  141. package/dist-cli/chunks/inspect-XAEZTCMI.js +0 -2
  142. package/dist-cli/chunks/install-desktop-2CSEI2MD.js +0 -2
  143. package/dist-cli/chunks/mode-VPVEZ652.js +0 -111
  144. package/dist-cli/chunks/optional-demo-registry-D47EWM4J.js +0 -2
  145. package/dist-cli/chunks/runtime-EV7TFPWL.js +0 -2
  146. package/dist-cli/chunks/store-ANJJMDLX.js +0 -2
  147. package/dist-cli/chunks/telemetry-GZK77NUU.js +0 -2
  148. package/dist-cli/chunks/upload-KAY6K5ML.js +0 -2
  149. package/dist-cli/chunks/web-PI2BL42A.js +0 -2
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.215 | (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-T4EGFOSE.js";import{g as A,i as _}from"./chunk-5MUXEXEW.js";import"./chunk-OUB7WT7Q.js";import{b as k}from"./chunk-YTQ5RCVB.js";import"./chunk-FEFLFVIU.js";import"./chunk-AKNZ6QBL.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.216 | (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-G6VHJWGQ.js";import{g as A,i as _}from"./chunk-SPKRGAWR.js";import"./chunk-VURHG6DO.js";import{b as k}from"./chunk-YN44PKW5.js";import"./chunk-RESHDGBU.js";import"./chunk-J74AW22R.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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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;
@@ -44,6 +44,91 @@ var fs = __toESM(require("fs"), 1);
44
44
  var path = __toESM(require("path"), 1);
45
45
  var import_playwright = require("playwright");
46
46
 
47
+ // ../../scripts/lib/reap-browser.ts
48
+ var import_node_child_process = require("node:child_process");
49
+ function rootChromePid(b) {
50
+ const w = b;
51
+ if (w && typeof w.process === "function") {
52
+ try {
53
+ const p = w.process();
54
+ if (p && typeof p.pid === "number" && p.pid > 0) return p.pid;
55
+ } catch {
56
+ }
57
+ }
58
+ if (w && typeof w.browser === "function") {
59
+ try {
60
+ const child = w.browser();
61
+ if (child) return rootChromePid(child);
62
+ } catch {
63
+ }
64
+ }
65
+ return null;
66
+ }
67
+ function killTree(pid) {
68
+ let kids = [];
69
+ try {
70
+ kids = (0, import_node_child_process.execSync)(`pgrep -P ${pid} || true`).toString().split("\n").filter(Boolean);
71
+ } catch {
72
+ }
73
+ for (const k of kids) killTree(Number(k));
74
+ try {
75
+ process.kill(pid, "SIGKILL");
76
+ } catch {
77
+ }
78
+ }
79
+ var reapPids = /* @__PURE__ */ new Set();
80
+ var installed = false;
81
+ function installReaper() {
82
+ if (installed) return;
83
+ installed = true;
84
+ const reap = () => {
85
+ for (const pid of reapPids) killTree(pid);
86
+ };
87
+ process.on("SIGTERM", () => {
88
+ reap();
89
+ process.exit(0);
90
+ });
91
+ process.on("SIGINT", () => {
92
+ reap();
93
+ process.exit(0);
94
+ });
95
+ process.on("exit", reap);
96
+ }
97
+ async function launchReapedScoped(launch) {
98
+ const browser = await launch();
99
+ const root = rootChromePid(browser);
100
+ const mine = /* @__PURE__ */ new Set();
101
+ if (root != null) {
102
+ mine.add(root);
103
+ reapPids.add(root);
104
+ installReaper();
105
+ }
106
+ const evented = browser;
107
+ if (typeof evented.on === "function") {
108
+ evented.on("disconnected", () => {
109
+ for (const pid of mine) reapPids.delete(pid);
110
+ });
111
+ }
112
+ const reapNow = () => {
113
+ for (const pid of mine) {
114
+ killTree(pid);
115
+ reapPids.delete(pid);
116
+ }
117
+ mine.clear();
118
+ };
119
+ return { browser, reapNow };
120
+ }
121
+ function gpuChromeArgs() {
122
+ const angle = process.platform === "darwin" ? "metal" : process.platform === "linux" ? "vulkan" : "default";
123
+ return [
124
+ `--use-angle=${angle}`,
125
+ "--enable-gpu",
126
+ "--enable-gpu-rasterization",
127
+ "--enable-zero-copy",
128
+ "--ignore-gpu-blocklist"
129
+ ];
130
+ }
131
+
47
132
  // detox/gestures.ts
48
133
  async function waitForSootsimGestureHandler(page, viewTag, handlerName) {
49
134
  await page.waitForFunction(
@@ -743,6 +828,7 @@ var BASE_URL = process.env.SOOTSIM_URL || "http://localhost:5173";
743
828
  var SCREENSHOT_DIR = process.env.SOOTSIM_SCREENSHOT_DIR || path.join(process.cwd(), "test", "detox-driver", "screenshots");
744
829
  var DETOX_PLATFORM = process.env.SOOTSIM_PLATFORM === "android" ? "android" : "ios";
745
830
  var _browser = null;
831
+ var _reapBrowserNow = null;
746
832
  var _context = null;
747
833
  var _page = null;
748
834
  var _synchronizationEnabled = false;
@@ -874,6 +960,8 @@ async function waitForSootsimShellReady(page, timeout = 3e4) {
874
960
  }
875
961
  };
876
962
  const isTenantOnly = new URL(window.location.href).searchParams.get("renderMode") === "tenant-only";
963
+ const currentUrl = new URL(window.location.href);
964
+ const expectsInitialAppPaint = currentUrl.searchParams.has("test") || currentUrl.pathname.includes("/app/");
877
965
  let shellHost = null;
878
966
  while (Date.now() < deadline) {
879
967
  const candidate = window.SootSim?.bridges?.shellHost;
@@ -890,7 +978,7 @@ async function waitForSootsimShellReady(page, timeout = 3e4) {
890
978
  if (shellHost.ready && typeof shellHost.ready.then === "function") {
891
979
  await withTimeout("sootsim shell ready", shellHost.ready);
892
980
  }
893
- if (shellHost.firstContentPainted && typeof shellHost.firstContentPainted.then === "function") {
981
+ if (!expectsInitialAppPaint && shellHost.firstContentPainted && typeof shellHost.firstContentPainted.then === "function") {
894
982
  await withTimeout(
895
983
  "sootsim shell first content paint",
896
984
  shellHost.firstContentPainted
@@ -970,9 +1058,15 @@ async function closeContext() {
970
1058
  async function closeBrowser() {
971
1059
  if (!_browser) return;
972
1060
  const browser = _browser;
1061
+ const reapBrowserNow = _reapBrowserNow;
973
1062
  _browser = null;
1063
+ _reapBrowserNow = null;
974
1064
  await closeContext();
975
- await browser.close();
1065
+ try {
1066
+ await browser.close();
1067
+ } finally {
1068
+ reapBrowserNow?.();
1069
+ }
976
1070
  }
977
1071
  async function waitForSootsimIdle(page, maxMs = 3e3) {
978
1072
  const result = await page.evaluate(
@@ -1557,10 +1651,16 @@ var device = {
1557
1651
  _platform: DETOX_PLATFORM,
1558
1652
  async launchApp(opts) {
1559
1653
  if (!_browser) {
1560
- _browser = await import_playwright.chromium.launch({
1561
- headless: true,
1562
- args: ["--enable-unsafe-webgpu", "--enable-features=Vulkan"]
1563
- });
1654
+ const launched = await launchReapedScoped(
1655
+ () => import_playwright.chromium.launch({
1656
+ channel: "chrome",
1657
+ headless: true,
1658
+ args: [...gpuChromeArgs(), "--enable-unsafe-webgpu"],
1659
+ ignoreDefaultArgs: ["--enable-unsafe-swiftshader"]
1660
+ })
1661
+ );
1662
+ _browser = launched.browser;
1663
+ _reapBrowserNow = launched.reapNow;
1564
1664
  }
1565
1665
  if (!_page || opts?.newInstance || opts?.delete || opts?.recordVideoDir) {
1566
1666
  await closeContext();
@@ -1914,11 +2014,7 @@ var device = {
1914
2014
  var sootExpect = createExpect(findNodeByMatcher, getPage);
1915
2015
  var sootWaitFor = createWaitFor(findNodeByMatcher, getPage);
1916
2016
  async function cleanup() {
1917
- if (_browser) {
1918
- await _browser.close();
1919
- _browser = null;
1920
- _page = null;
1921
- }
2017
+ await closeBrowser();
1922
2018
  }
1923
2019
  // Annotate the CommonJS export names for ESM import in node:
1924
2020
  0 && (module.exports = {
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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;
@@ -1551,6 +1551,7 @@ async function tapResolvedTarget(bridge, args) {
1551
1551
  } catch {
1552
1552
  }
1553
1553
  const deadline = Date.now() + timing.deadlineMs;
1554
+ let lastOffscreenAt = null;
1554
1555
  while (Date.now() <= deadline || attempts === 0) {
1555
1556
  attempts++;
1556
1557
  const payload = await args.resolve();
@@ -1559,14 +1560,30 @@ async function tapResolvedTarget(bridge, args) {
1559
1560
  return { payload, result: null, attempts, failure: "special" };
1560
1561
  }
1561
1562
  if (payload && typeof payload.cx === "number" && typeof payload.cy === "number") {
1562
- const result = await bridge.send({
1563
- type: "tap",
1564
- x: payload.cx,
1565
- y: payload.cy,
1566
- target: tapTargetFromPayload(payload, args.textFallback)
1567
- });
1568
- lastResult = result;
1569
- if (isTapSuccess(result)) return { payload, result, attempts };
1563
+ if (payload.offscreen) {
1564
+ lastResult = {
1565
+ hit: false,
1566
+ reason: "offscreen",
1567
+ x: payload.cx,
1568
+ y: payload.cy,
1569
+ screen: payload.screen
1570
+ };
1571
+ const at = `${Math.round(payload.cx)},${Math.round(payload.cy)}`;
1572
+ if (lastOffscreenAt === at) {
1573
+ return { payload, result: lastResult, attempts, failure: "missed" };
1574
+ }
1575
+ lastOffscreenAt = at;
1576
+ } else {
1577
+ lastOffscreenAt = null;
1578
+ const result = await bridge.send({
1579
+ type: "tap",
1580
+ x: payload.cx,
1581
+ y: payload.cy,
1582
+ target: tapTargetFromPayload(payload, args.textFallback)
1583
+ });
1584
+ lastResult = result;
1585
+ if (isTapSuccess(result)) return { payload, result, attempts };
1586
+ }
1570
1587
  }
1571
1588
  const remaining = deadline - Date.now();
1572
1589
  if (remaining <= 0) break;
@@ -1621,9 +1638,17 @@ async function tapById(bridge, query, opts = {}) {
1621
1638
  resolved && typeof resolved.cy === 'number'
1622
1639
  ? resolved.cy
1623
1640
  : n.absolutePosition.y + (n.layout.height || 0) / 2
1641
+ const scrEl = document.querySelector('canvas[data-surface-id]')
1642
+ const scr =
1643
+ scrEl && scrEl.clientWidth > 40 && scrEl.clientHeight > 40
1644
+ ? { width: scrEl.clientWidth, height: scrEl.clientHeight }
1645
+ : null
1646
+ const offscreen =
1647
+ !!scr && (cx < 0 || cy < 0 || cx > scr.width || cy > scr.height)
1624
1648
  return {
1625
1649
  cx,
1626
1650
  cy,
1651
+ ...(offscreen ? { offscreen: true, screen: scr } : {}),
1627
1652
  match: {
1628
1653
  nodeId: n.nodeId ?? null,
1629
1654
  id: n.id,
@@ -1764,9 +1789,17 @@ async function tapByText(bridge, query, options = {}, opts = {}) {
1764
1789
  resolved && typeof resolved.cy === 'number'
1765
1790
  ? resolved.cy
1766
1791
  : n.absolutePosition.y + (n.layout.height || 0) / 2
1792
+ const scrEl = document.querySelector('canvas[data-surface-id]')
1793
+ const scr =
1794
+ scrEl && scrEl.clientWidth > 40 && scrEl.clientHeight > 40
1795
+ ? { width: scrEl.clientWidth, height: scrEl.clientHeight }
1796
+ : null
1797
+ const offscreen =
1798
+ !!scr && (cx < 0 || cy < 0 || cx > scr.width || cy > scr.height)
1767
1799
  return {
1768
1800
  cx,
1769
1801
  cy,
1802
+ ...(offscreen ? { offscreen: true, screen: scr } : {}),
1770
1803
  match: {
1771
1804
  nodeId: n.nodeId ?? null,
1772
1805
  id: n.id,
@@ -1819,6 +1852,12 @@ async function tapBest(bridge, query, opts = {}) {
1819
1852
  absolutePosition: byTestId.absolutePosition,
1820
1853
  layout: byTestId.layout,
1821
1854
  },
1855
+ screen: (() => {
1856
+ const el = document.querySelector('canvas[data-surface-id]')
1857
+ return el && el.clientWidth > 40 && el.clientHeight > 40
1858
+ ? { width: el.clientWidth, height: el.clientHeight }
1859
+ : null
1860
+ })(),
1822
1861
  }
1823
1862
  }
1824
1863
  const byText = await t.findByText(${arg})
@@ -1834,6 +1873,12 @@ async function tapBest(bridge, query, opts = {}) {
1834
1873
  absolutePosition: byText.absolutePosition,
1835
1874
  layout: byText.layout,
1836
1875
  },
1876
+ screen: (() => {
1877
+ const el = document.querySelector('canvas[data-surface-id]')
1878
+ return el && el.clientWidth > 40 && el.clientHeight > 40
1879
+ ? { width: el.clientWidth, height: el.clientHeight }
1880
+ : null
1881
+ })(),
1837
1882
  }
1838
1883
  }
1839
1884
  return { strategy: 'none' }
@@ -1843,10 +1888,13 @@ async function tapBest(bridge, query, opts = {}) {
1843
1888
  const node = payload.node;
1844
1889
  const cx = node.absolutePosition.x + node.layout.width / 2;
1845
1890
  const cy = node.absolutePosition.y + node.layout.height / 2;
1891
+ const screen = payload.screen ?? null;
1892
+ const offscreen = !!screen && (cx < 0 || cy < 0 || cx > screen.width || cy > screen.height);
1846
1893
  return {
1847
1894
  ...payload,
1848
1895
  cx,
1849
1896
  cy,
1897
+ ...offscreen ? { offscreen: true, screen } : {},
1850
1898
  target: {
1851
1899
  id: node.id,
1852
1900
  testID: node.testID,
package/dist-lib/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.215 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // cli/commands/inspect/core.ts
4
4
  function resolveMaxMsFlag(args, fallbackMs) {
@@ -1461,6 +1461,7 @@ async function tapResolvedTarget(bridge, args) {
1461
1461
  } catch {
1462
1462
  }
1463
1463
  const deadline = Date.now() + timing.deadlineMs;
1464
+ let lastOffscreenAt = null;
1464
1465
  while (Date.now() <= deadline || attempts === 0) {
1465
1466
  attempts++;
1466
1467
  const payload = await args.resolve();
@@ -1469,14 +1470,30 @@ async function tapResolvedTarget(bridge, args) {
1469
1470
  return { payload, result: null, attempts, failure: "special" };
1470
1471
  }
1471
1472
  if (payload && typeof payload.cx === "number" && typeof payload.cy === "number") {
1472
- const result = await bridge.send({
1473
- type: "tap",
1474
- x: payload.cx,
1475
- y: payload.cy,
1476
- target: tapTargetFromPayload(payload, args.textFallback)
1477
- });
1478
- lastResult = result;
1479
- if (isTapSuccess(result)) return { payload, result, attempts };
1473
+ if (payload.offscreen) {
1474
+ lastResult = {
1475
+ hit: false,
1476
+ reason: "offscreen",
1477
+ x: payload.cx,
1478
+ y: payload.cy,
1479
+ screen: payload.screen
1480
+ };
1481
+ const at = `${Math.round(payload.cx)},${Math.round(payload.cy)}`;
1482
+ if (lastOffscreenAt === at) {
1483
+ return { payload, result: lastResult, attempts, failure: "missed" };
1484
+ }
1485
+ lastOffscreenAt = at;
1486
+ } else {
1487
+ lastOffscreenAt = null;
1488
+ const result = await bridge.send({
1489
+ type: "tap",
1490
+ x: payload.cx,
1491
+ y: payload.cy,
1492
+ target: tapTargetFromPayload(payload, args.textFallback)
1493
+ });
1494
+ lastResult = result;
1495
+ if (isTapSuccess(result)) return { payload, result, attempts };
1496
+ }
1480
1497
  }
1481
1498
  const remaining = deadline - Date.now();
1482
1499
  if (remaining <= 0) break;
@@ -1531,9 +1548,17 @@ async function tapById(bridge, query, opts = {}) {
1531
1548
  resolved && typeof resolved.cy === 'number'
1532
1549
  ? resolved.cy
1533
1550
  : n.absolutePosition.y + (n.layout.height || 0) / 2
1551
+ const scrEl = document.querySelector('canvas[data-surface-id]')
1552
+ const scr =
1553
+ scrEl && scrEl.clientWidth > 40 && scrEl.clientHeight > 40
1554
+ ? { width: scrEl.clientWidth, height: scrEl.clientHeight }
1555
+ : null
1556
+ const offscreen =
1557
+ !!scr && (cx < 0 || cy < 0 || cx > scr.width || cy > scr.height)
1534
1558
  return {
1535
1559
  cx,
1536
1560
  cy,
1561
+ ...(offscreen ? { offscreen: true, screen: scr } : {}),
1537
1562
  match: {
1538
1563
  nodeId: n.nodeId ?? null,
1539
1564
  id: n.id,
@@ -1674,9 +1699,17 @@ async function tapByText(bridge, query, options = {}, opts = {}) {
1674
1699
  resolved && typeof resolved.cy === 'number'
1675
1700
  ? resolved.cy
1676
1701
  : n.absolutePosition.y + (n.layout.height || 0) / 2
1702
+ const scrEl = document.querySelector('canvas[data-surface-id]')
1703
+ const scr =
1704
+ scrEl && scrEl.clientWidth > 40 && scrEl.clientHeight > 40
1705
+ ? { width: scrEl.clientWidth, height: scrEl.clientHeight }
1706
+ : null
1707
+ const offscreen =
1708
+ !!scr && (cx < 0 || cy < 0 || cx > scr.width || cy > scr.height)
1677
1709
  return {
1678
1710
  cx,
1679
1711
  cy,
1712
+ ...(offscreen ? { offscreen: true, screen: scr } : {}),
1680
1713
  match: {
1681
1714
  nodeId: n.nodeId ?? null,
1682
1715
  id: n.id,
@@ -1729,6 +1762,12 @@ async function tapBest(bridge, query, opts = {}) {
1729
1762
  absolutePosition: byTestId.absolutePosition,
1730
1763
  layout: byTestId.layout,
1731
1764
  },
1765
+ screen: (() => {
1766
+ const el = document.querySelector('canvas[data-surface-id]')
1767
+ return el && el.clientWidth > 40 && el.clientHeight > 40
1768
+ ? { width: el.clientWidth, height: el.clientHeight }
1769
+ : null
1770
+ })(),
1732
1771
  }
1733
1772
  }
1734
1773
  const byText = await t.findByText(${arg})
@@ -1744,6 +1783,12 @@ async function tapBest(bridge, query, opts = {}) {
1744
1783
  absolutePosition: byText.absolutePosition,
1745
1784
  layout: byText.layout,
1746
1785
  },
1786
+ screen: (() => {
1787
+ const el = document.querySelector('canvas[data-surface-id]')
1788
+ return el && el.clientWidth > 40 && el.clientHeight > 40
1789
+ ? { width: el.clientWidth, height: el.clientHeight }
1790
+ : null
1791
+ })(),
1747
1792
  }
1748
1793
  }
1749
1794
  return { strategy: 'none' }
@@ -1753,10 +1798,13 @@ async function tapBest(bridge, query, opts = {}) {
1753
1798
  const node = payload.node;
1754
1799
  const cx = node.absolutePosition.x + node.layout.width / 2;
1755
1800
  const cy = node.absolutePosition.y + node.layout.height / 2;
1801
+ const screen = payload.screen ?? null;
1802
+ const offscreen = !!screen && (cx < 0 || cy < 0 || cx > screen.width || cy > screen.height);
1756
1803
  return {
1757
1804
  ...payload,
1758
1805
  cx,
1759
1806
  cy,
1807
+ ...offscreen ? { offscreen: true, screen } : {},
1760
1808
  target: {
1761
1809
  id: node.id,
1762
1810
  testID: node.testID,