sootsim 0.0.3 → 0.1.36

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 (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -4
  3. package/dist-cli/bin.js +12 -12
  4. package/dist-cli/chunks/{agent-D5NBV32O.js → agent-YZB6D3DR.js} +4 -4
  5. package/dist-cli/chunks/agent-wrapper-VHCVS22I.js +15 -0
  6. package/dist-cli/chunks/{assert-EJ7DQS2H.js → assert-AIVCKKLG.js} +2 -2
  7. package/dist-cli/chunks/auto-bootstrap-MLNTX23H.js +2 -0
  8. package/dist-cli/chunks/chunk-27P763IZ.js +61 -0
  9. package/dist-cli/chunks/chunk-3UIWOHC2.js +62 -0
  10. package/dist-cli/chunks/chunk-5KGFHWVR.js +1 -0
  11. package/dist-cli/chunks/chunk-5QIUJNT3.js +5 -0
  12. package/dist-cli/chunks/{chunk-RLS6PHBW.js → chunk-6GGMKFWJ.js} +1 -1
  13. package/dist-cli/chunks/{chunk-CQ6PX2EU.js → chunk-6Z275LCY.js} +2 -2
  14. package/dist-cli/chunks/chunk-75LBYBKW.js +11 -0
  15. package/dist-cli/chunks/chunk-A5BRCXYE.js +2 -0
  16. package/dist-cli/chunks/{chunk-FTRI7SVV.js → chunk-CYCXOAVZ.js} +2 -2
  17. package/dist-cli/chunks/{chunk-5IPP4HAW.js → chunk-DFN3GGH7.js} +2 -2
  18. package/dist-cli/chunks/chunk-EBEHZJRG.js +117 -0
  19. package/dist-cli/chunks/{chunk-3SLEIN6B.js → chunk-EJLNUMMP.js} +1 -1
  20. package/dist-cli/chunks/{chunk-3K6VDPVD.js → chunk-EWSQSALM.js} +2 -2
  21. package/dist-cli/chunks/{chunk-NKJLTISU.js → chunk-FE7UI3MT.js} +4 -4
  22. package/dist-cli/chunks/chunk-G663654J.js +1 -0
  23. package/dist-cli/chunks/chunk-G7XQD4KC.js +4 -0
  24. package/dist-cli/chunks/chunk-GW7XY5KC.js +2 -0
  25. package/dist-cli/chunks/{chunk-O2HBPZW5.js → chunk-H2QO4TDV.js} +2 -2
  26. package/dist-cli/chunks/{chunk-UZL5ZZ4E.js → chunk-HWCKZXNJ.js} +2 -2
  27. package/dist-cli/chunks/{chunk-BYLX2DO4.js → chunk-HWFHBMAQ.js} +2 -2
  28. package/dist-cli/chunks/chunk-IJMYFYDZ.js +2 -0
  29. package/dist-cli/chunks/chunk-J7CTD37P.js +1 -0
  30. package/dist-cli/chunks/{chunk-44CBTM22.js → chunk-KAXZHEKM.js} +1 -1
  31. package/dist-cli/chunks/{chunk-P5C3UASK.js → chunk-LHDWH7VS.js} +1 -1
  32. package/dist-cli/chunks/{chunk-H3JVJXOC.js → chunk-N32NCVL2.js} +2 -2
  33. package/dist-cli/chunks/{chunk-D4JFMCXD.js → chunk-NIZBR7EK.js} +2 -2
  34. package/dist-cli/chunks/{chunk-XJBPH4JR.js → chunk-NYY36OKU.js} +12 -12
  35. package/dist-cli/chunks/{chunk-SUZR2SZZ.js → chunk-OXN2PEB7.js} +1 -1
  36. package/dist-cli/chunks/{chunk-46LRF7PH.js → chunk-PJL25JQV.js} +1 -1
  37. package/dist-cli/chunks/{chunk-OG5CKIPC.js → chunk-RMW5BO3S.js} +2 -2
  38. package/dist-cli/chunks/chunk-SHO54NET.js +2 -0
  39. package/dist-cli/chunks/chunk-SMVJOWSV.js +16 -0
  40. package/dist-cli/chunks/chunk-TC6V7YFC.js +3 -0
  41. package/dist-cli/chunks/{chunk-VI3VW5BL.js → chunk-VFDRZNPN.js} +1 -1
  42. package/dist-cli/chunks/{chunk-AFTHIY3L.js → chunk-YIO6S3R5.js} +1 -1
  43. package/dist-cli/chunks/{chunk-X2W4IRXK.js → chunk-YLIIVTTQ.js} +2 -2
  44. package/dist-cli/chunks/chunk-YR7BGGYE.js +2 -0
  45. package/dist-cli/chunks/chunk-ZEW3RF5Q.js +1 -0
  46. package/dist-cli/chunks/{compat-5KSMOWLB.js → compat-Y2O2U7FL.js} +2 -2
  47. package/dist-cli/chunks/{config-NJB6PQHU.js → config-SRBOFUCI.js} +2 -2
  48. package/dist-cli/chunks/control-PL2V2O6S.js +2 -0
  49. package/dist-cli/chunks/daemon-IZC32PZW.js +50 -0
  50. package/dist-cli/chunks/{debug-QVOBTTLP.js → debug-BIDMW2PE.js} +3 -3
  51. package/dist-cli/chunks/demo-app-registry-5JFOUU3D.js +2 -0
  52. package/dist-cli/chunks/{detox-ZZSNZL4T.js → detox-B3FDOIS3.js} +2 -2
  53. package/dist-cli/chunks/{device-PQB3YGHN.js → device-ZZSI363W.js} +2 -2
  54. package/dist-cli/chunks/drivers-S4NGK4DB.js +2 -0
  55. package/dist-cli/chunks/{electron-JB26VHOO.js → electron-5YFHXEOI.js} +3 -3
  56. package/dist-cli/chunks/flow-JJBO6TFY.js +2 -0
  57. package/dist-cli/chunks/{hints-IGYDXXDS.js → hints-G5HBBV2O.js} +2 -2
  58. package/dist-cli/chunks/home-paths-VWC3FWA3.js +2 -0
  59. package/dist-cli/chunks/{inspect-DSU6ELRM.js → inspect-POOPWUQI.js} +66 -62
  60. package/dist-cli/chunks/install-MP6FHXNZ.js +2 -0
  61. package/dist-cli/chunks/install-desktop-2MYEI4FM.js +23 -0
  62. package/dist-cli/chunks/{install-dev-desktop-4DP3UY2X.js → install-dev-desktop-SKH3KEHY.js} +2 -2
  63. package/dist-cli/chunks/{keys-R5LAPAAL.js → keys-7PNASIQR.js} +2 -2
  64. package/dist-cli/chunks/{launch-K3WJV4QA.js → launch-JNS47LAQ.js} +3 -3
  65. package/dist-cli/chunks/login-YWZWUHBS.js +26 -0
  66. package/dist-cli/chunks/logout-O6SXMSBP.js +2 -0
  67. package/dist-cli/chunks/{maestro-YALWKKGU.js → maestro-CW6XVUKV.js} +3 -3
  68. package/dist-cli/chunks/{preview-D35EEONY.js → preview-WGKJO5FS.js} +2 -2
  69. package/dist-cli/chunks/{profile-MAF7NM5Q.js → profile-SUOBRPIC.js} +2 -2
  70. package/dist-cli/chunks/{record-ZCPQNGFW.js → record-QPWLYH5R.js} +2 -2
  71. package/dist-cli/chunks/runtime-KEMO2MSB.js +25 -0
  72. package/dist-cli/chunks/{screenshot-NQVZYC3C.js → screenshot-JTY46V7G.js} +2 -2
  73. package/dist-cli/chunks/{screenshot-mode-E45D2ZFH.js → screenshot-mode-7OYBBX6D.js} +2 -2
  74. package/dist-cli/chunks/{screenshots-I4SQI4DA.js → screenshots-QISKC4GD.js} +2 -2
  75. package/dist-cli/chunks/server-YSFJAKAV.js +34 -0
  76. package/dist-cli/chunks/setup-repo-LFB3HBEO.js +2 -0
  77. package/dist-cli/chunks/{skills-N4U63E5W.js → skills-MO7BFNVM.js} +2 -2
  78. package/dist-cli/chunks/store-6MFL53I4.js +2 -0
  79. package/dist-cli/chunks/telemetry-CN42GMVC.js +2 -0
  80. package/dist-cli/chunks/{test-VBD6N3AR.js → test-XUI3KNNQ.js} +3 -3
  81. package/dist-cli/chunks/upload-6FUT7AX5.js +2 -0
  82. package/dist-cli/chunks/{whoami-4K6JGMWH.js → whoami-TQFHY42N.js} +2 -2
  83. package/dist-lib/agent-daemon-client.cjs +3 -1
  84. package/dist-lib/agent-events.cjs +1 -1
  85. package/dist-lib/agent-sessions.cjs +2 -1
  86. package/dist-lib/attached-projects.cjs +1 -1
  87. package/dist-lib/auth/shared-session.cjs +1 -1
  88. package/dist-lib/backend-origin.cjs +1 -1
  89. package/dist-lib/bridge-constants.cjs +1 -1
  90. package/dist-lib/cli-constants.cjs +1 -1
  91. package/dist-lib/config.cjs +1 -1
  92. package/dist-lib/dev-bundle-resolution.cjs +3 -1
  93. package/dist-lib/home-paths.cjs +29 -3
  94. package/dist-lib/host/bridge-host.cjs +499 -59
  95. package/dist-lib/index.cjs +2 -2
  96. package/dist-lib/metro.cjs +2 -2
  97. package/dist-lib/render-mode.cjs +1 -1
  98. package/dist-lib/vite-base.cjs +800 -102
  99. package/dist-lib/vite.cjs +1 -1
  100. package/package.json +5 -3
  101. package/dist-cli/chunks/agent-wrapper-Y7I5QGHM.js +0 -15
  102. package/dist-cli/chunks/auto-bootstrap-Q7GNLISM.js +0 -2
  103. package/dist-cli/chunks/chunk-2FPPPJE5.js +0 -2
  104. package/dist-cli/chunks/chunk-3WPAEUOO.js +0 -1
  105. package/dist-cli/chunks/chunk-4RYT6AQV.js +0 -16
  106. package/dist-cli/chunks/chunk-5AG24UFX.js +0 -119
  107. package/dist-cli/chunks/chunk-BU3TZP4Y.js +0 -11
  108. package/dist-cli/chunks/chunk-CPMW2QLM.js +0 -1
  109. package/dist-cli/chunks/chunk-EEBR5YP5.js +0 -62
  110. package/dist-cli/chunks/chunk-EQ7G3UHS.js +0 -4
  111. package/dist-cli/chunks/chunk-LV5U7TI4.js +0 -1
  112. package/dist-cli/chunks/chunk-REYWQVAH.js +0 -2
  113. package/dist-cli/chunks/chunk-USRNDVQ3.js +0 -2
  114. package/dist-cli/chunks/chunk-WUYJFYOW.js +0 -2
  115. package/dist-cli/chunks/chunk-ZSRMXBGK.js +0 -2
  116. package/dist-cli/chunks/control-2F3AGZAO.js +0 -2
  117. package/dist-cli/chunks/daemon-MLG65V4S.js +0 -49
  118. package/dist-cli/chunks/demo-app-registry-XRYNJ4GC.js +0 -2
  119. package/dist-cli/chunks/drivers-GWDQEGWD.js +0 -2
  120. package/dist-cli/chunks/flow-7JRQXMFV.js +0 -2
  121. package/dist-cli/chunks/home-paths-CEGSGQTD.js +0 -2
  122. package/dist-cli/chunks/install-K6IJKADG.js +0 -65
  123. package/dist-cli/chunks/install-desktop-SC3LNFFF.js +0 -23
  124. package/dist-cli/chunks/login-A23PYJAW.js +0 -26
  125. package/dist-cli/chunks/logout-AJ24PH5O.js +0 -2
  126. package/dist-cli/chunks/runtime-Z2WIXYUN.js +0 -25
  127. package/dist-cli/chunks/server-ZUXKJRR5.js +0 -29
  128. package/dist-cli/chunks/store-4A6X4GBJ.js +0 -2
  129. package/dist-cli/chunks/upload-Y6FZ5XF2.js +0 -2
@@ -1,6 +1,6 @@
1
- /*! sootsim v0.0.3 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTHIY3L.js";import{a as Y,b as E,c as C,d as z,e as ie,f as V,g as te,h as Ie,i as Fe,j as fe}from"./chunk-FTRI7SVV.js";import{a as Te,e as ae}from"./chunk-UZL5ZZ4E.js";import{a as me,c as pe,d as xe}from"./chunk-5AG24UFX.js";import{g as Ae}from"./chunk-BU3TZP4Y.js";import"./chunk-REYWQVAH.js";import{a as Me}from"./chunk-SUZR2SZZ.js";import"./chunk-USRNDVQ3.js";import{a as we}from"./chunk-WUYJFYOW.js";import{c as $e,e as Se,f as ke,h as ve}from"./chunk-4RYT6AQV.js";import"./chunk-RLS6PHBW.js";import"./chunk-LV5U7TI4.js";import"./chunk-EQ7G3UHS.js";import"./chunk-2FPPPJE5.js";import"./chunk-46LRF7PH.js";import"./chunk-P5C3UASK.js";import{existsSync as ut,mkdirSync as mt,readFileSync as pt,rmSync as Pe,writeFileSync as ft}from"fs";import{tmpdir as gt}from"os";import{dirname as yt,join as bt,resolve as ht}from"path";var oe=1,wt="SOOTSIM_INSPECT_NOTICE_PATH",xt=300*1e3,$t=15e3;function Oe(){return ht(process.env[wt]||bt(gt(),"sootsim-inspect-notice-state.json"))}function St(o,c){return Object.fromEntries(Object.entries(o).filter(([,i])=>typeof i?.signature=="string"&&Number.isFinite(i?.updatedAt)&&c-i.updatedAt<=xt))}function kt(o){let c=Oe();if(!ut(c))return{version:oe,entries:{}};try{let i=JSON.parse(pt(c,"utf8"));return i.version!==oe||!i.entries||typeof i.entries!="object"?(Pe(c,{force:!0}),{version:oe,entries:{}}):{version:oe,entries:St(i.entries,o)}}catch{return Pe(c,{force:!0}),{version:oe,entries:{}}}}function vt(o){let c=Oe();mt(yt(c),{recursive:!0}),ft(c,JSON.stringify(o,null,2)+`
3
- `)}function Tt(o,c){let i=c.trim()||"default";return`${o}:${i}`}function ge(o,c,i,d={}){let u=d.nowMs??Date.now(),a=d.cooldownMs??$t,b=kt(u),k=Tt(o,c),$=b.entries[k];return $&&$.signature===i&&u-$.updatedAt<a?!1:(b.entries[k]={signature:i,updatedAt:u},vt(b),!0)}async function Ee(o,c={args:[]}){let i=await o.send({type:"evaluate",code:"(async () => await window.__sootsimTest.getNodeCount())()"}),d=typeof i=="number"?i:0;if(E(c.args)){C({nodes:d});return}console.log(` nodes: ${d}`)}function ye(o,c){let i=o.indexOf(c);return i>=0&&i+1<o.length?o[i+1]:null}async function Re(o){let{bridge:c,args:i,positional:d}=o,u=i.includes("--verbose")||i.includes("-v"),a=E(i),b=u&&!a,k=i.includes("--watch")||i.includes("-w"),$=1e3,I=i.includes("--compact"),y=i.includes("--no-xy"),S=ye(i,"--testid-like"),A=ye(i,"--only"),v=ye(i,"--subtree"),j=d[1],l=j?/[*?]/.test(j):!1,R=!l&&!A?j:void 0,D=A??(l?j:void 0),q=async()=>{await ie(c,{verbose:b});let Z=`(async () => {
1
+ /*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as U}from"./chunk-N32NCVL2.js";import{a as Ne,b as _e}from"./chunk-YIO6S3R5.js";import{a as Y,b as E,c as C,d as z,e as ie,f as V,g as te,h as Ie,i as Fe,j as fe}from"./chunk-CYCXOAVZ.js";import{a as Te,e as ae}from"./chunk-HWCKZXNJ.js";import{a as me,c as pe,d as xe}from"./chunk-EBEHZJRG.js";import{b as Ae,h as Pe}from"./chunk-75LBYBKW.js";import"./chunk-GW7XY5KC.js";import{a as Me}from"./chunk-OXN2PEB7.js";import"./chunk-YR7BGGYE.js";import"./chunk-PJL25JQV.js";import"./chunk-G663654J.js";import"./chunk-A5BRCXYE.js";import{a as we}from"./chunk-SHO54NET.js";import{c as $e,e as Se,f as ve,h as ke}from"./chunk-SMVJOWSV.js";import"./chunk-6GGMKFWJ.js";import"./chunk-ZEW3RF5Q.js";import"./chunk-5QIUJNT3.js";import"./chunk-LHDWH7VS.js";import{existsSync as mt,mkdirSync as pt,readFileSync as ft,rmSync as Oe,writeFileSync as gt}from"fs";import{tmpdir as yt}from"os";import{dirname as ht,join as bt,resolve as wt}from"path";var oe=1,xt="SOOTSIM_INSPECT_NOTICE_PATH",$t=300*1e3,St=15e3;function Ee(){return wt(process.env[xt]||bt(yt(),"sootsim-inspect-notice-state.json"))}function vt(o,c){return Object.fromEntries(Object.entries(o).filter(([,i])=>typeof i?.signature=="string"&&Number.isFinite(i?.updatedAt)&&c-i.updatedAt<=$t))}function kt(o){let c=Ee();if(!mt(c))return{version:oe,entries:{}};try{let i=JSON.parse(ft(c,"utf8"));return i.version!==oe||!i.entries||typeof i.entries!="object"?(Oe(c,{force:!0}),{version:oe,entries:{}}):{version:oe,entries:vt(i.entries,o)}}catch{return Oe(c,{force:!0}),{version:oe,entries:{}}}}function Tt(o){let c=Ee();pt(ht(c),{recursive:!0}),gt(c,JSON.stringify(o,null,2)+`
3
+ `)}function Mt(o,c){let i=c.trim()||"default";return`${o}:${i}`}function ge(o,c,i,d={}){let u=d.nowMs??Date.now(),a=d.cooldownMs??St,h=kt(u),v=Mt(o,c),$=h.entries[v];return $&&$.signature===i&&u-$.updatedAt<a?!1:(h.entries[v]={signature:i,updatedAt:u},Tt(h),!0)}async function Re(o,c={args:[]}){let i=await o.send({type:"evaluate",code:"(async () => await window.__sootsimTest.getNodeCount())()"}),d=typeof i=="number"?i:0;if(E(c.args)){C({nodes:d});return}console.log(` nodes: ${d}`)}function ye(o,c){let i=o.indexOf(c);return i>=0&&i+1<o.length?o[i+1]:null}async function Ce(o){let{bridge:c,args:i,positional:d}=o,u=i.includes("--verbose")||i.includes("-v"),a=E(i),h=u&&!a,v=i.includes("--watch")||i.includes("-w"),$=1e3,I=i.includes("--compact"),y=i.includes("--no-xy"),S=ye(i,"--testid-like"),A=ye(i,"--only"),k=ye(i,"--subtree"),j=d[1],l=j?/[*?]/.test(j):!1,R=!l&&!A?j:void 0,D=A??(l?j:void 0),q=async()=>{await ie(c,{verbose:h});let Z=`(async () => {
4
4
  const t = window.__sootsimTest
5
5
  const mainShell = window.SootSim?.bridges?.mainShell
6
6
  const kb = window.__sootsimKeyboard
@@ -11,33 +11,33 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
11
11
  shell = typeof mainShell?.getState === 'function' ? await mainShell.getState() : null
12
12
  } catch {}
13
13
 
14
- const tree = await t.dumpTree(12, ${JSON.stringify({describe:!0,verbose:u,filter:R||"",testIdLike:S||void 0,onlyGlob:D||void 0,subtreeRoot:v||void 0,compact:I,hideXy:y})})
14
+ const tree = await t.dumpTree(12, ${JSON.stringify({describe:!0,verbose:u,filter:R||"",testIdLike:S||void 0,onlyGlob:D||void 0,subtreeRoot:k||void 0,compact:I,hideXy:y})})
15
15
  const nodeCount = (await t.getNodeCount?.()) || 0
16
16
  const keyboard = kb && typeof kb.getLayout === 'function' ? kb.getLayout() : null
17
17
  return { tree, shell, nodeCount, keyboard }
18
- })()`,x=await c.send({type:"evaluate",code:Z}),J=x?.tree,H=x?.shell,K=x?.keyboard;if(a){C({shell:H,tree:J??"",keyboard:K});return}if(H&&typeof H=="object"){let e=[H.state?`state=${H.state}`:null,H.activeApp?`app=${H.activeApp}`:null,H.showSwitcher?"switcher":null,H.switcherPhase&&H.switcherPhase!=="idle"?`phase=${H.switcherPhase}`:null].filter(Boolean);e.length>0&&console.log(` shell: ${e.join(" ")}`)}if(typeof J=="string"&&J.startsWith("__SUBTREE_NOT_FOUND__:")){let e=J.slice(22);console.log(` subtree root not found: ${e}`),U("subtree-root-not-found",e);return}if(!J){let e=x?.nodeCount??0;console.log(" no matching nodes found"),!(R||S||D||v)&&e<10&&U("app-still-loading",e);return}if(console.log(J),!(R||S||D||v)&&!k&&J.split(`
18
+ })()`,x=await c.send({type:"evaluate",code:Z}),J=x?.tree,H=x?.shell,K=x?.keyboard;if(a){C({shell:H,tree:J??"",keyboard:K});return}if(H&&typeof H=="object"){let e=[H.state?`state=${H.state}`:null,H.activeApp?`app=${H.activeApp}`:null,H.showSwitcher?"switcher":null,H.switcherPhase&&H.switcherPhase!=="idle"?`phase=${H.switcherPhase}`:null].filter(Boolean);e.length>0&&console.log(` shell: ${e.join(" ")}`)}if(typeof J=="string"&&J.startsWith("__SUBTREE_NOT_FOUND__:")){let e=J.slice(22);console.log(` subtree root not found: ${e}`),U("subtree-root-not-found",e);return}if(!J){let e=x?.nodeCount??0;console.log(" no matching nodes found"),!(R||S||D||k)&&e<10&&U("app-still-loading",e);return}if(console.log(J),!(R||S||D||k)&&!v&&J.split(`
19
19
  `).length>=80&&U("describe-use-filters"),K&&K.visible){let e=K.spec,t=[e?.keyboardType?`type=${e.keyboardType}`:null,e?.returnKeyType&&e.returnKeyType!=="default"?`return=${e.returnKeyType}`:null,K.mode!=="letters"?`mode=${K.mode}`:null,K.shifted?"shift":null,K.capsLock?"caps":null,e?.autoCapitalize&&e.autoCapitalize!=="sentences"?`autoCap=${e.autoCapitalize}`:null,K.accessoryBarId?`accessory=${K.accessoryBarId}`:null].filter(Boolean);console.log(`
20
- keyboard: ${t.join(" ")||"visible"}`)}};if(k)for(console.log(` watching... (Ctrl+C to stop)
21
- `);;)console.clear(),await q(),await Y($);else await q()}var Mt=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function Ce(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let o of Mt){let c=process.env[o];if(c&&c.trim()&&c!=="0")return!0}return!1}async function Be(o){let{bridge:c,args:i,effectiveArgs:d,positional:u,inspectUsage:a}=o,b=x=>{let J=d.indexOf(x);return J>=0&&J+1<d.length?d[J+1]:null},k=x=>d.includes(x),$=b("--testid")||b("--test-id"),I=b("--role"),y=b("--type"),S=b("--text"),A=k("--pressable"),v=k("--visible"),j=!$&&!I&&!y&&!S&&!A&&!v?u[1]:null,l=S??j,R,D;$?(D="testid",R=`(async () => {
20
+ keyboard: ${t.join(" ")||"visible"}`)}};if(v)for(console.log(` watching... (Ctrl+C to stop)
21
+ `);;)console.clear(),await q(),await Y($);else await q()}var Nt=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function De(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let o of Nt){let c=process.env[o];if(c&&c.trim()&&c!=="0")return!0}return!1}async function Le(o){let{bridge:c,args:i,effectiveArgs:d,positional:u,inspectUsage:a}=o,h=x=>{let J=d.indexOf(x);return J>=0&&J+1<d.length?d[J+1]:null},v=x=>d.includes(x),$=h("--testid")||h("--test-id"),I=h("--role"),y=h("--type"),S=h("--text"),A=v("--pressable"),k=v("--visible"),j=!$&&!I&&!y&&!S&&!A&&!k?u[1]:null,l=S??j,R,D;$?(D="testid",R=`(async () => {
22
22
  const t = window.__sootsimTest
23
23
  return (await t.findByTestId(${JSON.stringify($)})) || (await t.findById(${JSON.stringify($)}))
24
24
  })()`):I?(D="role",R=`(async () => await window.__sootsimTest.queryAll({ hasRole: ${JSON.stringify(I)}, pruneHidden: true }))()`):y?(D="type",R=`(async () => await window.__sootsimTest.queryAll({ type: ${JSON.stringify(y)}, pruneHidden: true }))()`):A?(D="pressable",R=`(async () => {
25
25
  const t = window.__sootsimTest
26
26
  const all = await t.queryAll({ pruneHidden: true })
27
27
  return all.filter(n => n.pressable)
28
- })()`):v?(D="visible",R=`(async () => {
28
+ })()`):k?(D="visible",R=`(async () => {
29
29
  const all = await window.__sootsimTest.queryAll({ pruneHidden: true })
30
30
  return all.filter(n => n.layout && n.layout.width > 0 && n.layout.height > 0)
31
- })()`):l?(D="text",R=`(async () => await window.__sootsimTest.findByText(${JSON.stringify(l)}))()`):(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible")),process.exit(1));let q=await c.send({type:"evaluate",code:R}),ne=E(i),Z=i.includes("--verbose")||i.includes("--dump");if(ne)C(q??null);else if(Array.isArray(q))if(q.length===0){console.log(` no ${D} nodes found`);let x=await c.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof x=="number"&&x<10&&U("app-still-loading",x)}else{console.log(` found ${q.length} node${q.length===1?"":"s"} (${D}):`);for(let x of q.slice(0,20)){let J=x.absolutePosition?`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`:"",H=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",K=x.text?` "${x.text.slice(0,30)}"`:"",Q=x.testID?` #${x.testID}`:"",e=x.pressable?" (tap)":"",t=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${t}${K}${Q} ${H} ${J}${e}`),Z&&console.log(De(JSON.stringify(x,null,2)," "))}q.length>20&&console.log(` ... and ${q.length-20} more`)}else if(q==null)console.log(` not found: ${l||$||I||y||""||D}`),$&&U("wait-selector-for-missing-testid",$);else{let x=q;if(x.type&&x.absolutePosition){let J=`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`,H=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",K=x.text?` "${x.text.slice(0,40)}"`:"",Q=x.testID?` #${x.testID}`:"",e=x.pressable?" (tap)":"",t=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${t}${K}${Q} ${H} ${J}${e}`),Z&&console.log(De(JSON.stringify(x,null,2)," "))}else console.log(JSON.stringify(q,null,2))}}function De(o,c){return o.split(`
31
+ })()`):l?(D="text",R=`(async () => await window.__sootsimTest.findByText(${JSON.stringify(l)}))()`):(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible")),process.exit(1));let q=await c.send({type:"evaluate",code:R}),ne=E(i),Z=i.includes("--verbose")||i.includes("--dump");if(ne)C(q??null);else if(Array.isArray(q))if(q.length===0){console.log(` no ${D} nodes found`);let x=await c.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof x=="number"&&x<10&&U("app-still-loading",x)}else{console.log(` found ${q.length} node${q.length===1?"":"s"} (${D}):`);for(let x of q.slice(0,20)){let J=x.absolutePosition?`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`:"",H=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",K=x.text?` "${x.text.slice(0,30)}"`:"",Q=x.testID?` #${x.testID}`:"",e=x.pressable?" (tap)":"",t=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${t}${K}${Q} ${H} ${J}${e}`),Z&&console.log(Be(JSON.stringify(x,null,2)," "))}q.length>20&&console.log(` ... and ${q.length-20} more`)}else if(q==null)console.log(` not found: ${l||$||I||y||""||D}`),$&&U("wait-selector-for-missing-testid",$);else{let x=q;if(x.type&&x.absolutePosition){let J=`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`,H=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",K=x.text?` "${x.text.slice(0,40)}"`:"",Q=x.testID?` #${x.testID}`:"",e=x.pressable?" (tap)":"",t=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${t}${K}${Q} ${H} ${J}${e}`),Z&&console.log(Be(JSON.stringify(x,null,2)," "))}else console.log(JSON.stringify(q,null,2))}}function Be(o,c){return o.split(`
32
32
  `).map(i=>c+i).join(`
33
- `)}async function Le(o,c={}){let i=await o.send({type:"evaluate",code:`(() => {
33
+ `)}async function je(o,c={}){let i=await o.send({type:"evaluate",code:`(() => {
34
34
  const kb = window.__sootsimKeyboard
35
35
  if (!kb || typeof kb.getLayout !== 'function') {
36
36
  return { error: 'keyboard bridge getLayout() not available' }
37
37
  }
38
38
  return kb.getLayout()
39
- })()`});if("error"in i&&(console.error(i.error),process.exit(1)),c.json){console.log(JSON.stringify(i,null,2));return}let{visible:d,spec:u,mode:a,shifted:b,capsLock:k,accessoryBarId:$}=i,I=[];I.push(`keyboard: ${d?"visible":"hidden"}`),u?(I.push(` type: ${u.keyboardType}`),I.push(` returnKey: ${u.returnKeyType}`),I.push(` autoCap: ${u.autoCapitalize}`),I.push(` autoCorrect: ${u.autoCorrect?"on":"off"}`),I.push(` appearance: ${u.keyboardAppearance}`),u.secureTextEntry&&I.push(" secureTextEntry: true"),u.enablesReturnKeyAutomatically&&I.push(` return: ${u.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):I.push(" spec: <none> (shown via dev-tools with no TextInput)"),I.push(` mode: ${a}${b?" (shifted)":""}${k?" (caps)":""}`),$&&I.push(` accessoryBar: ${$}`),console.log(I.join(`
40
- `))}async function je(o){let c=await o.bridge.listBrowsers();if(E(o.args)){C(c.map(i=>({...i,active:i.id===o.browserId})));return}Ae(c,o.browserId)}function X(o){return o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}KB`:`${(o/1024/1024).toFixed(1)}MB`}function le(o,c){return c<=0?"?":`${(o/c*100).toFixed(0)}%`}async function Je(o,c={args:[]}){let d=await o.send({type:"evaluate",code:`(async () => {
39
+ })()`});if("error"in i&&(console.error(i.error),process.exit(1)),c.json){console.log(JSON.stringify(i,null,2));return}let{visible:d,spec:u,mode:a,shifted:h,capsLock:v,accessoryBarId:$}=i,I=[];I.push(`keyboard: ${d?"visible":"hidden"}`),u?(I.push(` type: ${u.keyboardType}`),I.push(` returnKey: ${u.returnKeyType}`),I.push(` autoCap: ${u.autoCapitalize}`),I.push(` autoCorrect: ${u.autoCorrect?"on":"off"}`),I.push(` appearance: ${u.keyboardAppearance}`),u.secureTextEntry&&I.push(" secureTextEntry: true"),u.enablesReturnKeyAutomatically&&I.push(` return: ${u.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):I.push(" spec: <none> (shown via dev-tools with no TextInput)"),I.push(` mode: ${a}${h?" (shifted)":""}${v?" (caps)":""}`),$&&I.push(` accessoryBar: ${$}`),console.log(I.join(`
40
+ `))}async function Je(o){let c=await o.bridge.listBrowsers();if(E(o.args)){C(c.map(i=>({...i,active:i.id===o.browserId})));return}Pe(c,o.browserId)}function X(o){return o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}KB`:`${(o/1024/1024).toFixed(1)}MB`}function le(o,c){return c<=0?"?":`${(o/c*100).toFixed(0)}%`}async function He(o,c={args:[]}){let d=await o.send({type:"evaluate",code:`(async () => {
41
41
  const host = window.__sootsimRenderHost
42
42
  const stats = host?.queryStats ? await host.queryStats() : null
43
43
  const hostMem = performance.memory
@@ -70,12 +70,14 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
70
70
  ? resolved.cy
71
71
  : n.absolutePosition.y + (n.layout.height || 0) / 2
72
72
  return { x: cx, y: cy, testID: n.testID, text: n.text }
73
- })()`})??null}async function He(o,c={}){let i=await o.send({type:"evaluate",code:`(async () => {
73
+ })()`})??null}async function qe(o,c={}){let i=await o.send({type:"evaluate",code:`(async () => {
74
74
  const test = window.__sootsimTest
75
75
  const kb = window.__sootsimKeyboard
76
+ // host-side __sootsimTest is a Proxy that forwards every call to the
77
+ // tenant worker \u2014 every method returns a Promise, so we must await.
76
78
  const navSnap =
77
79
  test && typeof test.getNavigationSnapshot === 'function'
78
- ? test.getNavigationSnapshot()
80
+ ? await test.getNavigationSnapshot()
79
81
  : null
80
82
  const keyboard =
81
83
  kb && typeof kb.getLayout === 'function'
@@ -94,7 +96,7 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
94
96
  })()
95
97
  : null
96
98
  return { nav: navSnap, keyboard }
97
- })()`}),d=i?.nav??null,u=i?.keyboard??null,a=await V(o,500).catch(()=>null);if(c.json){console.log(JSON.stringify({shell:a??null,nav:d,keyboard:u},null,2));return}let b=[];if(a){let k=a.activeApp??a.state??"<none>",$=a.showSwitcher?" (app switcher open)":"",I=typeof a.launchProgress=="number"&&a.launchProgress<.98?` launching (${Math.round(a.launchProgress*100)}%)`:"";b.push(`shell: ${k}${$}${I}`)}else b.push("shell: <unavailable>");if(d){let k=d.transitionPhase!=="idle"?` (${d.transitionPhase}, ${d.activeTransitionCount} active)`:"";if(b.push(`nav: phase=${d.transitionPhase}${k}`),d.screens.length===0)b.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let $ of d.screens){let I=$.isActive?"\u25B6":" ",y=$.routeName?` ${$.routeName}`:"",S=$.headerHeight>0?` header=${$.headerHeight}`:"",A=$.largeTitleState&&$.largeTitleState!=="expanded"?` large-title=${$.largeTitleState}`:"";b.push(` ${I} #${$.id}${y}${S}${A}`)}}else b.push("nav: <runtime not available>");if(u&&u.visible){let k=u.spec?.keyboardType??"default",$=u.spec?.returnKeyType??"default";b.push(`keyboard: visible (${k}, return=${$}, mode=${u.mode??"?"})`)}else b.push("keyboard: hidden");console.log(b.join(`
99
+ })()`}),d=i?.nav??null,u=i?.keyboard??null,a=await V(o,500).catch(()=>null);if(c.json){console.log(JSON.stringify({shell:a??null,nav:d,keyboard:u},null,2));return}let h=[];if(a){let v=a.activeApp??a.state??"<none>",$=a.showSwitcher?" (app switcher open)":"",I=typeof a.launchProgress=="number"&&a.launchProgress<.98?` launching (${Math.round(a.launchProgress*100)}%)`:"";h.push(`shell: ${v}${$}${I}`)}else h.push("shell: <unavailable>");if(d){let v=d.transitionPhase!=="idle"?` (${d.transitionPhase}, ${d.activeTransitionCount} active)`:"";if(h.push(`nav: phase=${d.transitionPhase}${v}`),d.screens.length===0)h.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let $ of d.screens){let I=$.isActive?"\u25B6":" ",y=$.routeName?` ${$.routeName}`:"",S=$.headerHeight>0?` header=${$.headerHeight}`:"",A=$.largeTitleState&&$.largeTitleState!=="expanded"?` large-title=${$.largeTitleState}`:"";h.push(` ${I} #${$.id}${y}${S}${A}`)}}else h.push("nav: <runtime not available>");if(u&&u.visible){let v=u.spec?.keyboardType??"default",$=u.spec?.returnKeyType??"default";h.push(`keyboard: visible (${v}, return=${$}, mode=${u.mode??"?"})`)}else h.push("keyboard: hidden");console.log(h.join(`
98
100
  `))}async function ee({bridge:o,maxMs:c,pollMs:i=50,stablePolls:d=3,strict:u=!1}){let a=await o.send({type:"evaluate",code:`(async () => {
99
101
  const start = Date.now()
100
102
  const deadline = start + ${Math.max(0,Math.round(c))}
@@ -144,7 +146,7 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
144
146
  await sleep(pollMs)
145
147
  }
146
148
  return { settled: false, elapsed: Date.now() - start }
147
- })()`}),{elapsed:b,settled:k}=a??{};return{elapsed:typeof b=="number"?b:c,settled:k===!0}}async function qe(o){let{bridge:c,args:i,positional:d}=o,u=d[1]?Number(d[1])*1e3:3e3,a=i.includes("--strict"),{elapsed:b,settled:k}=await ee({bridge:c,maxMs:u,strict:a});console.log(k?` settled in ${b}ms`:` timed out after ${b}ms (may still be animating)`)}async function We(o){let c=o.positional[1]?Number(o.positional[1]):.5;(!Number.isFinite(c)||c<0)&&(console.error(o.inspectUsage("sleep","[seconds]")),process.exit(1)),await Y(c*1e3),console.log(` slept ${c}s`)}async function ze(o){let{bridge:c,args:i,positional:d}=o,u=d[1]?Number(d[1]):5,a=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.dumpTree(${u}))()`});if(E(i)){C({depth:u,tree:a??null});return}console.log(typeof a=="string"?a:JSON.stringify(a,null,2))}async function Ke(o,c={args:[]}){let i=await o.send({type:"evaluate",code:"window.location.href"}),d=typeof i=="string"?i:"";if(E(c.args)){C({url:d});return}console.log(d)}async function Ue(o){let{wsPort:c,commandTimeoutMs:i,browserId:d,positional:u}=o,a=u[1]?Number(u[1]):30,b=Math.max(1e3,(Number.isFinite(a)?a:30)*1e3),k=Math.max(1,Math.ceil(b/500));console.log(" waiting for browser reconnect...");let $=await Ie(c,i,d,{attempts:k});$||(console.error(" timed out waiting for browser reconnect"),process.exit(1)),$.bridge.close(),ae({source:"inspect wait",step:{wait:b},summary:`wait ${Math.round(b/1e3)}s`}),console.log(` ready: ${$.count} nodes`)}async function Ye(o){let{bridge:c,args:i}=o,d=i.includes("--strict"),u=i.indexOf("--max-ms"),a=u>=0&&i[u+1]?Math.max(100,Number(i[u+1])):3e3,{elapsed:b,settled:k}=await ee({bridge:c,maxMs:a,strict:d});k?console.log(` idle in ${b}ms`):(console.error(` \u26A0 wait idle timed out after ${b}ms (may still be animating)`),process.exit(1))}async function Ge(o){let{bridge:c,args:i}=o,d=2e4,u=i.indexOf("--max-ms");u>=0&&i[u+1]&&(d=Math.max(100,Number(i[u+1])));let a=Date.now(),b=a+d,k=`(async () => {
149
+ })()`}),{elapsed:h,settled:v}=a??{};return{elapsed:typeof h=="number"?h:c,settled:v===!0}}async function We(o){let{bridge:c,args:i,positional:d}=o,u=d[1]?Number(d[1])*1e3:3e3,a=i.includes("--strict"),{elapsed:h,settled:v}=await ee({bridge:c,maxMs:u,strict:a});console.log(v?` settled in ${h}ms`:` timed out after ${h}ms (may still be animating)`)}async function ze(o){let c=o.positional[1]?Number(o.positional[1]):.5;(!Number.isFinite(c)||c<0)&&(console.error(o.inspectUsage("sleep","[seconds]")),process.exit(1)),await Y(c*1e3),console.log(` slept ${c}s`)}async function Ke(o){let{bridge:c,args:i,positional:d}=o,u=d[1]?Number(d[1]):5,a=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.dumpTree(${u}))()`});if(E(i)){C({depth:u,tree:a??null});return}console.log(typeof a=="string"?a:JSON.stringify(a,null,2))}async function Ue(o,c={args:[]}){let i=await o.send({type:"evaluate",code:"window.location.href"}),d=typeof i=="string"?i:"";if(E(c.args)){C({url:d});return}console.log(d)}async function Ye(o){let{wsPort:c,commandTimeoutMs:i,browserId:d,positional:u}=o,a=u[1]?Number(u[1]):30,h=Math.max(1e3,(Number.isFinite(a)?a:30)*1e3),v=Math.max(1,Math.ceil(h/500));console.log(" waiting for browser reconnect...");let $=await Ie(c,i,d,{attempts:v});$||(console.error(" timed out waiting for browser reconnect"),process.exit(1)),$.bridge.close(),ae({source:"inspect wait",step:{wait:h},summary:`wait ${Math.round(h/1e3)}s`}),console.log(` ready: ${$.count} nodes`)}async function Ge(o){let{bridge:c,args:i}=o,d=i.includes("--strict"),u=i.indexOf("--max-ms"),a=u>=0&&i[u+1]?Math.max(100,Number(i[u+1])):3e3,{elapsed:h,settled:v}=await ee({bridge:c,maxMs:a,strict:d});v?console.log(` idle in ${h}ms`):(console.error(` \u26A0 wait idle timed out after ${h}ms (may still be animating)`),process.exit(1))}async function Xe(o){let{bridge:c,args:i}=o,d=2e4,u=i.indexOf("--max-ms");u>=0&&i[u+1]&&(d=Math.max(100,Number(i[u+1])));let a=Date.now(),h=a+d,v=`(async () => {
148
150
  const t = window.__sootsimTest
149
151
  let nodes = 0
150
152
  try { nodes = (await t?.getNodeCount?.()) || 0 } catch {}
@@ -153,9 +155,9 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
153
155
  at: (window).__sootsimExternalAppReadyAt || 0,
154
156
  nodes,
155
157
  }
156
- })()`,$={flag:void 0,at:0,nodes:0};for(;Date.now()<b;){try{$=await c.send({type:"evaluate",code:k})??$}catch{}if($.flag===!0){console.log(` ready in ${Date.now()-a}ms: ${$.nodes} nodes (flag)`);return}await new Promise(I=>setTimeout(I,150))}console.error(` \u26A0 wait ready timed out after ${Date.now()-a}ms \u2014 guest app did not emit sootsim:externalAppReady (nodes: ${$.nodes})`),process.exit(1)}async function Xe(o){let{bridge:c,args:i,positional:d,inspectUsage:u}=o,a=d[1];a||(console.error(u("wait selector","<testid> [--max-ms 5000]")),process.exit(1));let b=i.indexOf("--max-ms"),k=b>=0&&i[b+1]?Math.max(100,Number(i[b+1])):5e3,$=await c.send({type:"evaluate",code:`(async () => {
158
+ })()`,$={flag:void 0,at:0,nodes:0};for(;Date.now()<h;){try{$=await c.send({type:"evaluate",code:v})??$}catch{}if($.flag===!0){console.log(` ready in ${Date.now()-a}ms: ${$.nodes} nodes (flag)`);return}await new Promise(I=>setTimeout(I,150))}console.error(` \u26A0 wait ready timed out after ${Date.now()-a}ms \u2014 guest app did not emit sootsim:externalAppReady (nodes: ${$.nodes})`),process.exit(1)}async function Ve(o){let{bridge:c,args:i,positional:d,inspectUsage:u}=o,a=d[1];a||(console.error(u("wait selector","<testid> [--max-ms 5000]")),process.exit(1));let h=i.indexOf("--max-ms"),v=h>=0&&i[h+1]?Math.max(100,Number(i[h+1])):5e3,$=await c.send({type:"evaluate",code:`(async () => {
157
159
  const start = Date.now()
158
- const deadline = start + ${k}
160
+ const deadline = start + ${v}
159
161
  const t = window.__sootsimTest
160
162
  const find = async () => {
161
163
  try {
@@ -172,8 +174,8 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
172
174
  await new Promise((r) => setTimeout(r, 80))
173
175
  }
174
176
  return { found: false, elapsed: Date.now() - start }
175
- })()`}),{found:I,node:y,elapsed:S}=$??{};if(I&&y){let A=y.absolutePosition?`@(${Math.round(y.absolutePosition.x)},${Math.round(y.absolutePosition.y)})`:"",v=y.layout?`${Math.round(y.layout.width)}x${Math.round(y.layout.height)}`:"?x?";console.log(` found #${a} in ${S}ms ${v} ${A}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${S??k}ms`),process.exit(1)}function st(o){return o==null?"\u2014":o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}K`:`${(o/1024/1024).toFixed(1)}M`}function nt(o){return o==null?" \u2026":o<1e3?`${o}ms`.padStart(5):`${(o/1e3).toFixed(2)}s`.padStart(5)}function _t(o){return o.error?"err":o.status==null?" \u2026 ":String(o.status)}function Ve(o){let c=new Date(o.startTs).toLocaleTimeString(),i=_t(o).padEnd(3),d=o.method.padEnd(5),u=st(o.size).padStart(6),a=nt(o.durationMs);console.log(` [${c}] ${i} ${d} ${u} ${a} ${o.displayUrl}`),o.error&&console.log(` error: ${o.error}`)}function It(o){let c=[["id",o.id],["source",o.source],["kind",o.kind],["method",o.method],["status",o.error?`error: ${o.error}`:`${o.status??"\u2014"} ${o.statusText??""}`.trim()],["url",o.url],["started",new Date(o.startTs).toLocaleTimeString()],["duration",nt(o.durationMs).trim()],["size",st(o.size)],["content-type",o.type??"\u2014"]];for(let[i,d]of c)console.log(` ${i.padEnd(13)} ${d}`)}var Ft={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Ze="\x1B[0m",At="\x1B[2m";function Qe(o,c){let i=new Date(o.ts).toLocaleTimeString(),d=o.level.toUpperCase().padEnd(5),u=o.args.join(" ");if(c){let a=Ft[o.level];console.log(` ${At}[${i}]${Ze} ${a}${d}${Ze} ${u}`)}else console.log(` [${i}] ${d} ${u}`);if(o.stack&&o.level==="error"){let a=o.stack.split(`
176
- `).slice(0,5);for(let b of a)console.log(` ${b.trim()}`)}}var G="__sootsimCliPerf",Pt=120;async function et(o,c){let i=o.find((A,v)=>o[v-1]==="--id"),d=o.find((A,v)=>o[v-1]==="--text");if(i||d){let A=await c.send({type:"evaluate",code:Ne({id:i,text:d})});if(!A)throw new Error(i?`no node with id "${i}"`:`no node matching text "${d}"`);let{x:v,y:j,w:l,h:R}=A;return{x:v,y:j,w:l,h:R}}let u=o.find((A,v)=>o[v-1]==="--area");if(u){let A=u.split(",").map(D=>Number(D.trim()));if(A.length!==4||A.some(D=>!Number.isFinite(D)))throw new Error(`--area expects x,y,w,h (got "${u}")`);let[v,j,l,R]=A;return{x:v,y:j,w:l,h:R}}let a=A=>{let v=o.find((l,R)=>o[R-1]===A);if(v==null)return null;let j=Number(v);return Number.isFinite(j)?j:null},b=a("--x"),k=a("--y"),$=a("--w"),I=a("--h");if(b!=null||k!=null||$!=null||I!=null)return{x:b??0,y:k??0,w:$??1,h:I??1};let S=o.filter((A,v)=>v>0&&!A.startsWith("-")&&o[v-1]!=="--output"&&o[v-1]!=="--area"&&o[v-1]!=="--id"&&o[v-1]!=="--text"&&o[v-1]!=="--x"&&o[v-1]!=="--y"&&o[v-1]!=="--w"&&o[v-1]!=="--h").map(Number).filter(A=>Number.isFinite(A));if(S.length>=2){let[A,v,j=1,l=1]=S;return{x:A,y:v,w:j,h:l}}return null}function be(o){let c={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let i of o)i<8?c["<8"]++:i<12?c["8-12"]++:i<16?c["12-16"]++:i<20?c["16-20"]++:i<33?c["20-33"]++:c[">33"]++;console.log(" histogram:");for(let[i,d]of Object.entries(c)){let u="\u2588".repeat(Math.ceil(d/o.length*40));console.log(` ${i.padEnd(6)} ${u} ${d}`)}}async function de(o,c,i){let d=Date.now()+c,u=await V(o,c);for(;;){if(i(u))return{settled:!0,state:u};if(Date.now()>=d)return{settled:!1,state:u};await Y(16),u=await V(o)}}async function he(o){return o.send({type:"evaluate",code:`(async () => {
177
+ })()`}),{found:I,node:y,elapsed:S}=$??{};if(I&&y){let A=y.absolutePosition?`@(${Math.round(y.absolutePosition.x)},${Math.round(y.absolutePosition.y)})`:"",k=y.layout?`${Math.round(y.layout.width)}x${Math.round(y.layout.height)}`:"?x?";console.log(` found #${a} in ${S}ms ${k} ${A}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${S??v}ms`),process.exit(1)}function nt(o){return o==null?"\u2014":o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}K`:`${(o/1024/1024).toFixed(1)}M`}function rt(o){return o==null?" \u2026":o<1e3?`${o}ms`.padStart(5):`${(o/1e3).toFixed(2)}s`.padStart(5)}function It(o){return o.error?"err":o.status==null?" \u2026 ":String(o.status)}function Ze(o){let c=new Date(o.startTs).toLocaleTimeString(),i=It(o).padEnd(3),d=o.method.padEnd(5),u=nt(o.size).padStart(6),a=rt(o.durationMs);console.log(` [${c}] ${i} ${d} ${u} ${a} ${o.displayUrl}`),o.error&&console.log(` error: ${o.error}`)}function Ft(o){let c=[["id",o.id],["source",o.source],["kind",o.kind],["method",o.method],["status",o.error?`error: ${o.error}`:`${o.status??"\u2014"} ${o.statusText??""}`.trim()],["url",o.url],["started",new Date(o.startTs).toLocaleTimeString()],["duration",rt(o.durationMs).trim()],["size",nt(o.size)],["content-type",o.type??"\u2014"]];for(let[i,d]of c)console.log(` ${i.padEnd(13)} ${d}`)}var At={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Qe="\x1B[0m",Pt="\x1B[2m";function et(o,c){let i=new Date(o.ts).toLocaleTimeString(),d=o.level.toUpperCase().padEnd(5),u=o.args.join(" ");if(c){let a=At[o.level];console.log(` ${Pt}[${i}]${Qe} ${a}${d}${Qe} ${u}`)}else console.log(` [${i}] ${d} ${u}`);if(o.stack&&o.level==="error"){let a=o.stack.split(`
178
+ `).slice(0,5);for(let h of a)console.log(` ${h.trim()}`)}}var G="__sootsimCliPerf",Ot=120;async function tt(o,c){let i=o.find((A,k)=>o[k-1]==="--id"),d=o.find((A,k)=>o[k-1]==="--text");if(i||d){let A=await c.send({type:"evaluate",code:Ne({id:i,text:d})});if(!A)throw new Error(i?`no node with id "${i}"`:`no node matching text "${d}"`);let{x:k,y:j,w:l,h:R}=A;return{x:k,y:j,w:l,h:R}}let u=o.find((A,k)=>o[k-1]==="--area");if(u){let A=u.split(",").map(D=>Number(D.trim()));if(A.length!==4||A.some(D=>!Number.isFinite(D)))throw new Error(`--area expects x,y,w,h (got "${u}")`);let[k,j,l,R]=A;return{x:k,y:j,w:l,h:R}}let a=A=>{let k=o.find((l,R)=>o[R-1]===A);if(k==null)return null;let j=Number(k);return Number.isFinite(j)?j:null},h=a("--x"),v=a("--y"),$=a("--w"),I=a("--h");if(h!=null||v!=null||$!=null||I!=null)return{x:h??0,y:v??0,w:$??1,h:I??1};let S=o.filter((A,k)=>k>0&&!A.startsWith("-")&&o[k-1]!=="--output"&&o[k-1]!=="--area"&&o[k-1]!=="--id"&&o[k-1]!=="--text"&&o[k-1]!=="--x"&&o[k-1]!=="--y"&&o[k-1]!=="--w"&&o[k-1]!=="--h").map(Number).filter(A=>Number.isFinite(A));if(S.length>=2){let[A,k,j=1,l=1]=S;return{x:A,y:k,w:j,h:l}}return null}function he(o){let c={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let i of o)i<8?c["<8"]++:i<12?c["8-12"]++:i<16?c["12-16"]++:i<20?c["16-20"]++:i<33?c["20-33"]++:c[">33"]++;console.log(" histogram:");for(let[i,d]of Object.entries(c)){let u="\u2588".repeat(Math.ceil(d/o.length*40));console.log(` ${i.padEnd(6)} ${u} ${d}`)}}async function de(o,c,i){let d=Date.now()+c,u=await V(o,c);for(;;){if(i(u))return{settled:!0,state:u};if(Date.now()>=d)return{settled:!1,state:u};await Y(16),u=await V(o)}}async function be(o){return o.send({type:"evaluate",code:`(async () => {
177
179
  const kb = window.__sootsimKeyboard
178
180
  const test = window.__sootsimTest
179
181
  if (!kb) return { error: 'keyboard bridge not available' }
@@ -205,30 +207,32 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
205
207
  frame: runtimeSnapshot?.keyboard?.frame ?? null,
206
208
  focusedRect: runtimeSnapshot?.focused?.rect ?? null,
207
209
  }
208
- })()`})}async function Ot(o,c=600){let i=Date.now()+c;for(;Date.now()<=i;){let d=await he(o);if(d.visible)return d;await Y(30)}return he(o)}async function ue(o,c){let i=await he(o);if(i.visible)return i;console.error(` ${c} requires the iOS keyboard to be visible. focus an input first with sootsim do tap-id/tap-text or sootsim do type-into.`),process.exit(1)}async function tt(o,c,i){return c==="appearance"?o.send({type:"evaluate",code:`(async () => {
210
+ })()`})}async function Et(o,c=600){let i=Date.now()+c;for(;Date.now()<=i;){let d=await be(o);if(d.visible)return d;await Y(30)}return be(o)}async function ue(o,c){let i=await be(o);if(i.visible)return i;console.error(` ${c} requires the iOS keyboard to be visible. focus an input first with sootsim do tap-id/tap-text or sootsim do type-into.`),process.exit(1)}async function ot(o,c,i){return c==="appearance"?o.send({type:"evaluate",code:`(async () => {
209
211
  const requested = ${JSON.stringify(i??"toggle")}
210
212
  const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
211
213
  const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
212
- let applied = requested
214
+ let next = requested
213
215
  if (requested === 'toggle') {
214
- applied = inferredCurrent === 'dark' ? 'light' : 'dark'
215
- } else if (requested === 'auto') {
216
- applied = window.matchMedia?.('(prefers-color-scheme: dark)')?.matches ? 'dark' : 'light'
216
+ next = inferredCurrent === 'dark' ? 'light' : 'dark'
217
217
  }
218
- window.postMessage({ type: 'soot-action', action: 'set-appearance', value: applied }, '*')
219
- return { ok: true, requested, applied }
218
+ // engine accepts 'auto' since the schema picker landed; pass through.
219
+ window.postMessage({ type: 'soot-action', action: 'set-appearance', value: next }, '*')
220
+ const applied = next === 'auto'
221
+ ? (window.matchMedia?.('(prefers-color-scheme: dark)')?.matches ? 'dark' : 'light')
222
+ : next
223
+ return { ok: true, requested, value: next, applied }
220
224
  })()`}):o.send({type:"evaluate",code:`(async () => {
221
225
  window.dispatchEvent(new CustomEvent(${JSON.stringify(c==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
222
226
  return { ok: true, action: ${JSON.stringify(c)} }
223
- })()`})}function Et(o){let c={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(c[o])return c[o];let i=o.match(/^Digit([0-9])$/);if(i)return i[1];let d=o.match(/^Key([A-Z])$/);return d?d[1].toLowerCase():null}function Rt(o){if(typeof o!="string")return null;let c=o.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function rt(...o){for(let c of o){if(typeof c!="string")continue;let i=c.trim();if(i)return i}return null}async function L(o,c,i){ae({source:o,step:c,summary:i})}function Ct(o,c,i){if(!i||i.hit===!1)return null;let d=rt(i.responderTestID,i.testID);if(d)return{step:{tapOn:{id:d}},summary:`tap #${d}`};let u=Rt(i.text);return u?{step:{tapOn:u},summary:`tap "${u}"`}:{step:{tapAtCoords:{x:o,y:c}},summary:`tap @${Math.round(o)},${Math.round(c)}`}}function ot(o,c,i){let d=rt(c?.testID,c?.id);return d?{step:{tapOn:{id:d}},summary:`tap #${d}`}:i==="id"?{step:{tapOn:{id:o}},summary:`tap #${o}`}:{step:{tapOn:o},summary:`tap "${o}"`}}async function ss(o,c){let i=o[0]==="get"||o[0]==="do"||o[0]==="debug"||o[0]==="wait"?o[0]:null,d=i?o.slice(1):o,u=$e(d,{port:c.port,commandTimeoutMs:c.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--tail","-f","--internal"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--max-ms","--filter","--limit","--level"]}),a=u.positional,b=a[0],k=i==="get"||i==="do"||i==="debug"||i==="wait"?i:"inspect",$=typeof d[0]=="string"&&xe.has(d[0]),I=$?d[0]:null,y=e=>$&&e===d[0]?`sootsim ${e}`:`sootsim ${k} ${e}`,S=(e,t)=>` usage: ${y(e)}${t?` ${t}`:""}`;if(!b||o.includes("--help")||o.includes("-h")){let e={bridgePort:7668,defaultShellUrl:we};if(k==="do"||k==="get"||k==="debug"||k==="wait"){let r=me(k,e);r&&(console.log(`${r}
227
+ })()`})}function Rt(o){let c={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(c[o])return c[o];let i=o.match(/^Digit([0-9])$/);if(i)return i[1];let d=o.match(/^Key([A-Z])$/);return d?d[1].toLowerCase():null}function Ct(o){if(typeof o!="string")return null;let c=o.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function at(...o){for(let c of o){if(typeof c!="string")continue;let i=c.trim();if(i)return i}return null}async function L(o,c,i){ae({source:o,step:c,summary:i})}function Dt(o,c,i){if(!i||i.hit===!1)return null;let d=at(i.responderTestID,i.testID);if(d)return{step:{tapOn:{id:d}},summary:`tap #${d}`};let u=Ct(i.text);return u?{step:{tapOn:u},summary:`tap "${u}"`}:{step:{tapAtCoords:{x:o,y:c}},summary:`tap @${Math.round(o)},${Math.round(c)}`}}function st(o,c,i){let d=at(c?.testID,c?.id);return d?{step:{tapOn:{id:d}},summary:`tap #${d}`}:i==="id"?{step:{tapOn:{id:o}},summary:`tap #${o}`}:{step:{tapOn:o},summary:`tap "${o}"`}}async function rs(o,c){let i=o[0]==="get"||o[0]==="do"||o[0]==="debug"||o[0]==="wait"?o[0]:null,d=i?o.slice(1):o,u=$e(d,{port:c.port,commandTimeoutMs:c.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--tail","-f","--internal"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--max-ms","--filter","--limit","--level"]}),a=u.positional,h=a[0],v=i==="get"||i==="do"||i==="debug"||i==="wait"?i:"inspect",$=typeof d[0]=="string"&&xe.has(d[0]),I=$?d[0]:null,y=e=>$&&e===d[0]?`sootsim ${e}`:`sootsim ${v} ${e}`,S=(e,t)=>` usage: ${y(e)}${t?` ${t}`:""}`;if(!h||o.includes("--help")||o.includes("-h")){let e={bridgePort:7668,defaultShellUrl:we};if(v==="do"||v==="get"||v==="debug"||v==="wait"){let r=me(v,e);r&&(console.log(`${r}
224
228
  `),process.exit(0))}if(I==="shell"){let r=pe("shell",e);r&&(console.log(`${r}
225
229
  `),process.exit(0))}let t=pe("inspect",e),s=["do","get","debug","wait"].map(r=>me(r,e)).filter(r=>r!=null).join(`
226
230
 
227
231
  `);console.log(`${t??""}
228
232
 
229
233
  ${s}
230
- `),process.exit(0)}let A=u.wsPort,v=u.browserId,j=u.commandTimeoutMs;if(b==="list"&&d.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-GWDQEGWD.js"),t=e();console.log(` available drivers (${t.length}):
231
- `);let s=Math.max(...t.map(n=>n.id.length),6),r=Math.max(...t.map(n=>n.kind.length),4);for(let n of t){let m=n.available?"\u2713":"\u2717",p=n.id.padEnd(s),h=n.kind.padEnd(r);console.log(` ${m} ${p} ${h} ${n.description}`),n.available&&n.detail?console.log(` ${n.detail}`):!n.available&&n.reason&&console.log(` unavailable: ${n.reason}`)}return}let l=Se(u),R=v||"default",D=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]);function q(e){let t=e.displayUrl||e.url;return e.status!=null?`${e.method} ${t} -> ${e.status}${e.statusText?` ${e.statusText}`:""}`:e.error?`${e.method} ${t} -> ${e.error}`:`${e.method} ${t}`}async function ne(e){let t=Ce()?1200:350;try{let{settled:s,elapsed:r}=await ee({bridge:e,maxMs:t,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${r??t}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
234
+ `),process.exit(0)}let A=u.wsPort,k=u.browserId,j=u.commandTimeoutMs;if(h==="list"&&d.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-S4NGK4DB.js"),t=e();console.log(` available drivers (${t.length}):
235
+ `);let s=Math.max(...t.map(n=>n.id.length),6),r=Math.max(...t.map(n=>n.kind.length),4);for(let n of t){let m=n.available?"\u2713":"\u2717",p=n.id.padEnd(s),b=n.kind.padEnd(r);console.log(` ${m} ${p} ${b} ${n.description}`),n.available&&n.detail?console.log(` ${n.detail}`):!n.available&&n.reason&&console.log(` unavailable: ${n.reason}`)}return}let l=Se(u),R=k||"default",D=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]);function q(e){let t=e.displayUrl||e.url;return e.status!=null?`${e.method} ${t} -> ${e.status}${e.statusText?` ${e.statusText}`:""}`:e.error?`${e.method} ${t} -> ${e.error}`:`${e.method} ${t}`}async function ne(e){let t=De()?1200:350;try{let{settled:s,elapsed:r}=await ee({bridge:e,maxMs:t,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${r??t}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
232
236
  `)}catch{}}async function Z(){try{return await l.send({type:"evaluate",code:`(() => ({
233
237
  console: window.__sootsimConsole?.count?.() || null,
234
238
  requests: window.__sootsimTest?.getRequestCounts?.() || null,
@@ -238,7 +242,7 @@ ${s}
238
242
  `);for(let n of r){let m=new Date(n.timestamp).toLocaleTimeString();console.log(` [${m}] ${q(n)}`),n.responseBody?console.log(` ${n.responseBody}`):n.error&&console.log(` ${n.error}`)}}}async function J(e={}){let t=e.counts!==void 0?e.counts:await l.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!t||typeof t!="object")return;let s=t,r=Math.max(0,Number(s.errors)||0),n=Math.max(0,Number(s.warnings)||0);if(r===0&&n===0||!e.includeTail&&!ge("console",R,`${r}:${n}`))return;let m=[];if(r>0&&m.push(`${r} console error${r===1?"":"s"}`),n>0&&m.push(`${n} console warning${n===1?"":"s"}`),console.log(`
239
243
  console: ${m.join(", ")}`),console.log(` inspect: ${y("errors")} 5`),n>0&&console.log(` inspect: ${y("warnings")} 5`),!e.includeTail||r===0)return;let p=await l.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors?.(5) || []"});if(!(!Array.isArray(p)||p.length===0)){console.log(`
240
244
  recent console errors:
241
- `);for(let h of p){let f=new Date(h.timestamp).toLocaleTimeString(),w=Array.isArray(h.args)?h.args.map(O=>typeof O=="object"?JSON.stringify(O):String(O)).join(" "):String(h);console.log(` [${f}] ${w}`)}}}let H=new Set(["tap","double-tap","tap-text","tap-id","type","type-into","key","key-sequence","keycode","drag","swipe","long-press","touch","gesture","pinch","scroll","shell"]),K=new Set(["a11y","capture","count","double-tap","drag","find","gesture","layout","long-press","node","pinch","sample-color","scroll","screenshot","swipe","tap","tap-id","tap-text","touch","tree","type-into"]),Q=(o.includes("--verbose")||o.includes("-v"))&&!o.includes("--json");k==="do"&&b==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),H.has(b)&&await ke(l),K.has(b)&&await ie(l,{verbose:Q});try{switch(b){case"list":{await je({bridge:l,browserId:v,args:d});break}case"tree":{await ze({bridge:l,args:d,positional:a});break}case"a11y":{let e=a[1]?Number(a[1]):5,t=await l.send({type:"evaluate",code:`(async () => {
245
+ `);for(let b of p){let f=new Date(b.timestamp).toLocaleTimeString(),w=Array.isArray(b.args)?b.args.map(O=>typeof O=="object"?JSON.stringify(O):String(O)).join(" "):String(b);console.log(` [${f}] ${w}`)}}}let H=new Set(["tap","double-tap","tap-text","tap-id","type","type-into","key","key-sequence","keycode","drag","swipe","long-press","touch","gesture","pinch","scroll","shell"]),K=new Set(["a11y","capture","count","double-tap","drag","find","gesture","layout","long-press","node","pinch","sample-color","scroll","screenshot","swipe","tap","tap-id","tap-text","touch","tree","type-into"]),Q=(o.includes("--verbose")||o.includes("-v"))&&!o.includes("--json");v==="do"&&h==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),H.has(h)&&await ve(l),K.has(h)&&await ie(l,{verbose:Q});try{switch(h){case"list":{await Je({bridge:l,browserId:k,args:d});break}case"tree":{await Ke({bridge:l,args:d,positional:a});break}case"a11y":{let e=a[1]?Number(a[1]):5,t=await l.send({type:"evaluate",code:`(async () => {
242
246
  const t = window.__sootsimTest
243
247
  if (!t) return []
244
248
  const all = await t.queryAll({ pruneHidden: true })
@@ -267,7 +271,7 @@ ${s}
267
271
  size: n.layout ? { w: Math.round(n.layout.width), h: Math.round(n.layout.height) } : null,
268
272
  }))
269
273
  })()`});if(!Array.isArray(t)||t.length===0){console.log(" no accessible nodes found");break}if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{console.log(` accessibility tree (${t.length} nodes):
270
- `);for(let s of t){let r=[];if(r.push(`[${s.role}]`),s.label){let n=s.label.length>50?s.label.slice(0,47)+"...":s.label;r.push(`"${n}"`)}if(s.hint&&r.push(`(hint: "${s.hint}")`),s.testID&&r.push(`#${s.testID}`),s.state){let n=[];s.state.disabled&&n.push("disabled"),s.state.selected&&n.push("selected"),s.state.checked===!0&&n.push("checked"),s.state.checked==="mixed"&&n.push("mixed"),s.state.busy&&n.push("busy"),s.state.expanded===!0&&n.push("expanded"),s.state.expanded===!1&&n.push("collapsed"),n.length&&r.push(`{${n.join(", ")}}`)}s.position&&r.push(`@(${s.position.x},${s.position.y})`),s.size&&r.push(`${s.size.w}x${s.size.h}`),console.log(" "+r.join(" "))}}break}case"find":{await Be({bridge:l,args:o,effectiveArgs:d,positional:a,inspectUsage:S});break}case"count":{await Ee(l,{args:d});break}case"keyboard":{await Le(l,{json:o.includes("--json")});break}case"screens":{await He(l,{json:o.includes("--json")});break}case"memory":{await Je(l,{args:d});break}case"wait":{await Ue({wsPort:A,commandTimeoutMs:j,browserId:v,positional:a});break}case"sleep":{await We({positional:a,inspectUsage:S});break}case"settle":{await qe({bridge:l,args:o,positional:a});break}case"ready":{await Ge({bridge:l,args:o});break}case"idle":{await Ye({bridge:l,args:o,positional:a});break}case"selector":{await Xe({bridge:l,args:o,positional:a,inspectUsage:S});break}case"layout":{let e=a[1];e||(console.error(S("layout","<id>")),process.exit(1));let t=await l.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(e)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=o.find((h,f)=>o[f-1]==="--output")||"/tmp/sootsim-inspect.png",s=await et(o,l),r={type:"screenshot"};s&&(r.crop=s);let m=(await l.send(r)).replace(/^data:image\/png;base64,/,"");s&&console.log(` area: x=${s.x} y=${s.y} w=${s.w} h=${s.h}`),(await import("fs")).writeFileSync(t,Buffer.from(m,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let e=await et(o,l);e||(console.error(S("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let t=await l.send({type:"evaluate",code:_e(e)});if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:r,b:n,a:m,hex:p,samples:h}=t,f=e.w===1&&e.h===1?`@(${e.x},${e.y})`:`@(${e.x},${e.y}) ${e.w}x${e.h}`;console.log(` ${p} rgba(${s}, ${r}, ${n}, ${m}) ${f} ${h} samples`)}break}case"node":{let e=a[1];e||(console.error(S("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await l.send({type:"evaluate",code:`(async () => {
274
+ `);for(let s of t){let r=[];if(r.push(`[${s.role}]`),s.label){let n=s.label.length>50?s.label.slice(0,47)+"...":s.label;r.push(`"${n}"`)}if(s.hint&&r.push(`(hint: "${s.hint}")`),s.testID&&r.push(`#${s.testID}`),s.state){let n=[];s.state.disabled&&n.push("disabled"),s.state.selected&&n.push("selected"),s.state.checked===!0&&n.push("checked"),s.state.checked==="mixed"&&n.push("mixed"),s.state.busy&&n.push("busy"),s.state.expanded===!0&&n.push("expanded"),s.state.expanded===!1&&n.push("collapsed"),n.length&&r.push(`{${n.join(", ")}}`)}s.position&&r.push(`@(${s.position.x},${s.position.y})`),s.size&&r.push(`${s.size.w}x${s.size.h}`),console.log(" "+r.join(" "))}}break}case"find":{await Le({bridge:l,args:o,effectiveArgs:d,positional:a,inspectUsage:S});break}case"count":{await Re(l,{args:d});break}case"keyboard":{await je(l,{json:o.includes("--json")});break}case"screens":{await qe(l,{json:o.includes("--json")});break}case"memory":{await He(l,{args:d});break}case"wait":{await Ye({wsPort:A,commandTimeoutMs:j,browserId:k,positional:a});break}case"sleep":{await ze({positional:a,inspectUsage:S});break}case"settle":{await We({bridge:l,args:o,positional:a});break}case"ready":{await Xe({bridge:l,args:o});break}case"idle":{await Ge({bridge:l,args:o,positional:a});break}case"selector":{await Ve({bridge:l,args:o,positional:a,inspectUsage:S});break}case"layout":{let e=a[1];e||(console.error(S("layout","<id>")),process.exit(1));let t=await l.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(e)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=o.find((b,f)=>o[f-1]==="--output")||"/tmp/sootsim-inspect.png",s=await tt(o,l),r={type:"screenshot"};s&&(r.crop=s);let m=(await l.send(r)).replace(/^data:image\/png;base64,/,"");s&&console.log(` area: x=${s.x} y=${s.y} w=${s.w} h=${s.h}`),(await import("fs")).writeFileSync(t,Buffer.from(m,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let e=await tt(o,l);e||(console.error(S("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let t=await l.send({type:"evaluate",code:_e(e)});if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:r,b:n,a:m,hex:p,samples:b}=t,f=e.w===1&&e.h===1?`@(${e.x},${e.y})`:`@(${e.x},${e.y}) ${e.w}x${e.h}`;console.log(` ${p} rgba(${s}, ${r}, ${n}, ${m}) ${f} ${b} samples`)}break}case"node":{let e=a[1];e||(console.error(S("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await l.send({type:"evaluate",code:`(async () => {
271
275
  const t = window.__sootsimTest
272
276
  const q = ${JSON.stringify(e)}
273
277
  let node = null
@@ -323,17 +327,17 @@ ${s}
323
327
  transform,
324
328
  parentChain,
325
329
  }
326
- })()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let e=Number(a[1]),t=Number(a[2]),s=se(o);if(s){let m=await ce(l,s);m||(console.error(` not found: ${s.value}`),s.mode==="testid"&&U("wait-selector-for-missing-testid",s.value),process.exit(1)),e=m.x,t=m.y}(!Number.isFinite(e)||!Number.isFinite(t))&&(console.error(S("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await l.send({type:"tap",x:e,y:t}),n=Ct(e,t,r);n&&await L("inspect tap",n.step,n.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let e=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),n=b==="swipe"?10:12,m=b==="swipe"?8:16,p=a[5]?Number(a[5]):n,h=a[6]?Number(a[6]):m;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(p)||!Number.isFinite(h))&&(console.error(S(b,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await l.send({type:"evaluate",code:`(async () => {
330
+ })()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let e=Number(a[1]),t=Number(a[2]),s=se(o);if(s){let m=await ce(l,s);m||(console.error(` not found: ${s.value}`),s.mode==="testid"&&U("wait-selector-for-missing-testid",s.value),process.exit(1)),e=m.x,t=m.y}(!Number.isFinite(e)||!Number.isFinite(t))&&(console.error(S("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await l.send({type:"tap",x:e,y:t}),n=Dt(e,t,r);n&&await L("inspect tap",n.step,n.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let e=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),n=h==="swipe"?10:12,m=h==="swipe"?8:16,p=a[5]?Number(a[5]):n,b=a[6]?Number(a[6]):m;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(p)||!Number.isFinite(b))&&(console.error(S(h,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await l.send({type:"evaluate",code:`(async () => {
327
331
  const interact = window.__sootsimInteract
328
332
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
329
- const value = await interact.drag(${e}, ${t}, ${s}, ${r}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(h))})
333
+ const value = await interact.drag(${e}, ${t}, ${s}, ${r}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(b))})
330
334
  return { ok: !!value, value }
331
- })()`});if(f?.ok){let w=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,h)));await L(`inspect ${b}`,{swipe:{start:`${e}, ${t}`,end:`${s}, ${r}`,duration:w}},`${b} ${e},${t} -> ${s},${r}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let e=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),n=Number(a[5]),m=Number(a[6]),p=Number(a[7]),h=Number(a[8]),f=a[9]?Number(a[9]):12,w=a[10]?Number(a[10]):16;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(n)||!Number.isFinite(m)||!Number.isFinite(p)||!Number.isFinite(h)||!Number.isFinite(f)||!Number.isFinite(w))&&(console.error(S("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let O=await l.send({type:"evaluate",code:`(async () => {
335
+ })()`});if(f?.ok){let w=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,b)));await L(`inspect ${h}`,{swipe:{start:`${e}, ${t}`,end:`${s}, ${r}`,duration:w}},`${h} ${e},${t} -> ${s},${r}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let e=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),n=Number(a[5]),m=Number(a[6]),p=Number(a[7]),b=Number(a[8]),f=a[9]?Number(a[9]):12,w=a[10]?Number(a[10]):16;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(n)||!Number.isFinite(m)||!Number.isFinite(p)||!Number.isFinite(b)||!Number.isFinite(f)||!Number.isFinite(w))&&(console.error(S("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let O=await l.send({type:"evaluate",code:`(async () => {
332
336
  const interact = window.__sootsimInteract
333
337
  if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
334
- const value = await interact.pinch(${e}, ${t}, ${s}, ${r}, ${n}, ${m}, ${p}, ${h}, ${Math.max(1,Math.round(f))}, ${Math.max(0,Math.round(w))})
338
+ const value = await interact.pinch(${e}, ${t}, ${s}, ${r}, ${n}, ${m}, ${p}, ${b}, ${Math.max(1,Math.round(f))}, ${Math.max(0,Math.round(w))})
335
339
  return { ok: !!value, value }
336
- })()`});O?.ok&&await L("inspect pinch",{pinch:{from:[e,t,s,r],to:[n,m,p,h],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(w))}},`pinch (${e},${t}) (${s},${r}) -> (${n},${m}) (${p},${h})`),console.log(JSON.stringify(O,null,2));break}case"tap-text":{let e=a[1];e||(console.error(S("tap-text","<text>")),process.exit(1));let t=_=>{let P=o.indexOf(_);return P>=0&&P+1<o.length?o[P+1]:null},s=_=>o.includes(_),r=t("--nth")??t("--index"),n=r!==null?Number(r):null;n!==null&&!Number.isFinite(n)&&(console.error(` --nth/--index requires an integer, got: ${r}`),process.exit(1));let m=t("--within"),p=t("--role"),h=s("--exact"),f=s("--first"),w=t("--min-y"),O=t("--max-y"),B=t("--min-x"),N=t("--max-x");for(let[_,P]of[["--min-y",w],["--max-y",O],["--min-x",B],["--max-x",N]])P!==null&&!Number.isFinite(Number(P))&&(console.error(` ${_} requires a number, got: ${P}`),process.exit(1));let M=o.indexOf("--near"),F=null;if(M>=0){let _=Number(o[M+1]),P=Number(o[M+2]);(!Number.isFinite(_)||!Number.isFinite(P))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),F={x:_,y:P}}let W=JSON.stringify({query:e,exact:h,role:p,within:m,minX:B!==null?Number(B):null,maxX:N!==null?Number(N):null,minY:w!==null?Number(w):null,maxY:O!==null?Number(O):null,near:F,nth:n,first:f}),g=await l.send({type:"evaluate",code:`(async () => {
340
+ })()`});O?.ok&&await L("inspect pinch",{pinch:{from:[e,t,s,r],to:[n,m,p,b],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(w))}},`pinch (${e},${t}) (${s},${r}) -> (${n},${m}) (${p},${b})`),console.log(JSON.stringify(O,null,2));break}case"tap-text":{let e=a[1];e||(console.error(S("tap-text","<text>")),process.exit(1));let t=_=>{let P=o.indexOf(_);return P>=0&&P+1<o.length?o[P+1]:null},s=_=>o.includes(_),r=t("--nth")??t("--index"),n=r!==null?Number(r):null;n!==null&&!Number.isFinite(n)&&(console.error(` --nth/--index requires an integer, got: ${r}`),process.exit(1));let m=t("--within"),p=t("--role"),b=s("--exact"),f=s("--first"),w=t("--min-y"),O=t("--max-y"),B=t("--min-x"),N=t("--max-x");for(let[_,P]of[["--min-y",w],["--max-y",O],["--min-x",B],["--max-x",N]])P!==null&&!Number.isFinite(Number(P))&&(console.error(` ${_} requires a number, got: ${P}`),process.exit(1));let M=o.indexOf("--near"),F=null;if(M>=0){let _=Number(o[M+1]),P=Number(o[M+2]);(!Number.isFinite(_)||!Number.isFinite(P))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),F={x:_,y:P}}let W=JSON.stringify({query:e,exact:b,role:p,within:m,minX:B!==null?Number(B):null,maxX:N!==null?Number(N):null,minY:w!==null?Number(w):null,maxY:O!==null?Number(O):null,near:F,nth:n,first:f}),g=await l.send({type:"evaluate",code:`(async () => {
337
341
  const t = window.__sootsimTest
338
342
  if (!t) return { error: 'bridge-not-ready' }
339
343
  const F = ${W}
@@ -447,7 +451,7 @@ ${s}
447
451
  total,
448
452
  idx,
449
453
  }
450
- })()`});if(g?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),g?.ambiguous){let _=g.candidates;console.error(` ambiguous: ${g.total} matches for "${e}"`);for(let P of _){let re=P.abs?`@(${Math.round(P.abs.x)},${Math.round(P.abs.y)})`:"",at=P.layout?` ${P.layout.width}x${P.layout.height}`:"",it=P.testID?` #${P.testID}`:"",lt=P.text?` "${P.text}"`:"",ct=P.ancestorTestIDs.length>0?` within ${P.ancestorTestIDs.slice(0,3).map(dt=>`#${dt}`).join(" > ")}`:"";console.error(` [${P.idx}] <${P.type}>${lt}${it} ${re}${at}${ct}`)}g.total>_.length&&console.error(` ... and ${g.total-_.length} more`),console.error(" pick one:"),console.error(" --nth <index> pick the nth match (top-to-bottom, left-to-right; negatives from end)"),console.error(" --within <testID> narrow to descendants of a node"),console.error(" --min-y / --max-y geometric filter (pixels, absolute)"),console.error(" --min-x / --max-x geometric filter (pixels, absolute)"),console.error(" --near <x> <y> pick the closest match to a point"),console.error(" --exact exact text match (default is substring)"),console.error(" --role <role> narrow to accessibilityRole"),console.error(" --first keep the old pick-first-silently behavior"),process.exit(2)}g?.nthOutOfRange&&(console.error(` not found: nth ${g.nth} of ${g.total} match${g.total===1?"":"es"} for "${e}"`),process.exit(1)),(!g||typeof g.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let T=await l.send({type:"tap",x:g.cx,y:g.cy});if(T?.hit!==!1&&T?.ok!==!1){let _=ot(e,{id:g.target?.id??null,testID:g.target?.testID??null,type:g.target?.type??null,cx:g.cx,cy:g.cy},"text");await L("inspect tap-text",_.step,_.summary)}console.log(JSON.stringify({matched:g.match,tapped:{nodeId:g.target?.nodeId??null,id:g.target?.id??null,testID:g.target?.testID??null,type:g.target?.type??null,cx:g.cx,cy:g.cy},...g.strategy&&g.strategy!=="matched-node"?{strategy:g.strategy}:{},...g.total>1||n!==null?{nth:{index:g.idx,total:g.total}}:{},result:T},null,2));break}case"tap-id":{let e=a[1];e||(console.error(S("tap-id","<id>")),process.exit(1));let t=JSON.stringify(e),s=await l.send({type:"evaluate",code:`(async () => {
454
+ })()`});if(g?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),g?.ambiguous){let _=g.candidates;console.error(` ambiguous: ${g.total} matches for "${e}"`);for(let P of _){let re=P.abs?`@(${Math.round(P.abs.x)},${Math.round(P.abs.y)})`:"",it=P.layout?` ${P.layout.width}x${P.layout.height}`:"",lt=P.testID?` #${P.testID}`:"",ct=P.text?` "${P.text}"`:"",dt=P.ancestorTestIDs.length>0?` within ${P.ancestorTestIDs.slice(0,3).map(ut=>`#${ut}`).join(" > ")}`:"";console.error(` [${P.idx}] <${P.type}>${ct}${lt} ${re}${it}${dt}`)}g.total>_.length&&console.error(` ... and ${g.total-_.length} more`),console.error(" pick one:"),console.error(" --nth <index> pick the nth match (top-to-bottom, left-to-right; negatives from end)"),console.error(" --within <testID> narrow to descendants of a node"),console.error(" --min-y / --max-y geometric filter (pixels, absolute)"),console.error(" --min-x / --max-x geometric filter (pixels, absolute)"),console.error(" --near <x> <y> pick the closest match to a point"),console.error(" --exact exact text match (default is substring)"),console.error(" --role <role> narrow to accessibilityRole"),console.error(" --first keep the old pick-first-silently behavior"),process.exit(2)}g?.nthOutOfRange&&(console.error(` not found: nth ${g.nth} of ${g.total} match${g.total===1?"":"es"} for "${e}"`),process.exit(1)),(!g||typeof g.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let T=await l.send({type:"tap",x:g.cx,y:g.cy});if(T?.hit!==!1&&T?.ok!==!1){let _=st(e,{id:g.target?.id??null,testID:g.target?.testID??null,type:g.target?.type??null,cx:g.cx,cy:g.cy},"text");await L("inspect tap-text",_.step,_.summary)}console.log(JSON.stringify({matched:g.match,tapped:{nodeId:g.target?.nodeId??null,id:g.target?.id??null,testID:g.target?.testID??null,type:g.target?.type??null,cx:g.cx,cy:g.cy},...g.strategy&&g.strategy!=="matched-node"?{strategy:g.strategy}:{},...g.total>1||n!==null?{nth:{index:g.idx,total:g.total}}:{},result:T},null,2));break}case"tap-id":{let e=a[1];e||(console.error(S("tap-id","<id>")),process.exit(1));let t=JSON.stringify(e),s=await l.send({type:"evaluate",code:`(async () => {
451
455
  const t = window.__sootsimTest
452
456
  if (!t) return null
453
457
  const n = (await t.findByTestId(${t})) || (await t.findById(${t}))
@@ -482,7 +486,7 @@ ${s}
482
486
  },
483
487
  strategy: (resolved && resolved.strategy) || 'matched-node',
484
488
  }
485
- })()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let r=await l.send({type:"tap",x:s.cx,y:s.cy});if(r?.hit!==!1&&r?.ok!==!1){let n=ot(e,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await L("inspect tap-id",n.step,n.summary)}console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},result:r},null,2));break}case"type-into":{let e=a[1],t=a.slice(2).join(" ");(!e||!t)&&(console.error(S("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(e),r=await l.send({type:"evaluate",code:`(async () => {
489
+ })()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let r=await l.send({type:"tap",x:s.cx,y:s.cy});if(r?.hit!==!1&&r?.ok!==!1){let n=st(e,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await L("inspect tap-id",n.step,n.summary)}console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},result:r},null,2));break}case"type-into":{let e=a[1],t=a.slice(2).join(" ");(!e||!t)&&(console.error(S("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(e),r=await l.send({type:"evaluate",code:`(async () => {
486
490
  const t = window.__sootsimTest
487
491
  if (!t) return null
488
492
  const n = await (t.findByTestId(${s}) || t.findById(${s}))
@@ -494,7 +498,7 @@ ${s}
494
498
  isTextInput: !!n.isTextInput,
495
499
  placeholder: n.placeholder || null,
496
500
  }
497
- })()`});(!r||typeof r.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1)),r.isTextInput||console.error(` warning: ${e} is not a text input (isTextInput: false)`);let n=await l.send({type:"tap",x:r.cx,y:r.cy}),m=await Ot(l);m.visible||(console.error(` keyboard did not open after tapping ${e}`),process.exit(1));let p=m.focusedInput;p&&(p.testID===e||p.id===e||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(e)} but focus is on ${JSON.stringify(p.testID??p.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await l.send({type:"keyboard",action:"type",text:t}),await L("inspect type-into",{tapOn:{id:e},inputText:t},`type-into #${e} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:e,isTextInput:r.isTextInput,keyboardOpened:m.visible??n?.keyboardOpened??!1,focusedInput:m.focusedInput??null,typed:t},null,2));break}case"type":{let e=a.slice(1).join(" ");e||(console.error(S("type","<text>")),process.exit(1)),await ue(l,"type"),await l.send({type:"keyboard",action:"type",text:e}),await L("inspect type",{inputText:e},`type ${JSON.stringify(e)}`),console.log(` typed: ${JSON.stringify(e)}`);break}case"key":{let e=a[1];e||(console.error(S("key","<name>")),process.exit(1)),await ue(l,"key"),await l.send({type:"keyboard",action:"press",text:e}),await L("inspect key",{pressKey:e},`key ${e}`),console.log(` pressed: ${e}`);break}case"key-sequence":{let e=a.slice(1);e.length===0&&(console.error(S("key-sequence","<key> [<key> ...]")),process.exit(1)),await ue(l,"key-sequence");for(let t of e)await l.send({type:"keyboard",action:"press",text:t});await L("inspect key-sequence",{pressKey:e.join(" ")},`key-sequence ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"keycode":{let e=a.slice(1);e.length===0&&(console.error(S("keycode","<code> [<code> ...]")),process.exit(1));let t=e.map(r=>({code:r,key:Et(r)})),s=t.filter(r=>!r.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(r=>r.code).join(", ")}`),process.exit(1)),await ue(l,"keycode");for(let r of t)await l.send({type:"keyboard",action:"press",text:r.key});await L("inspect keycode",{pressKey:t.map(r=>r.key).join(" ")},`keycode ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"dispatch":{let e=a[1];e||(console.error(S("dispatch","<char>")),process.exit(1)),await l.send({type:"keyboard",action:"dispatchKey",text:e}),await L("inspect dispatch",{dispatchKey:e},`dispatch ${JSON.stringify(e)}`),console.log(` dispatched: ${e}`);break}case"dismiss":{await l.send({type:"keyboard",action:"dismiss"}),await L("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let e=Number(a[1]),t=Number(a[2]),s=se(o);if(s){let p=await ce(l,s);p||(console.error(` not found: ${s.value}`),s.mode==="testid"&&U("wait-selector-for-missing-testid",s.value),process.exit(1)),e=p.x,t=p.y}let r=a[3]?Number(a[3]):80;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(S("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let n=Math.max(0,Math.round(r)),m=await l.send({type:"evaluate",code:`(async () => {
501
+ })()`});(!r||typeof r.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1)),r.isTextInput||console.error(` warning: ${e} is not a text input (isTextInput: false)`);let n=await l.send({type:"tap",x:r.cx,y:r.cy}),m=await Et(l);m.visible||(console.error(` keyboard did not open after tapping ${e}`),process.exit(1));let p=m.focusedInput;p&&(p.testID===e||p.id===e||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(e)} but focus is on ${JSON.stringify(p.testID??p.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await l.send({type:"keyboard",action:"type",text:t}),await L("inspect type-into",{tapOn:{id:e},inputText:t},`type-into #${e} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:e,isTextInput:r.isTextInput,keyboardOpened:m.visible??n?.keyboardOpened??!1,focusedInput:m.focusedInput??null,typed:t},null,2));break}case"type":{let e=a.slice(1).join(" ");e||(console.error(S("type","<text>")),process.exit(1)),await ue(l,"type"),await l.send({type:"keyboard",action:"type",text:e}),await L("inspect type",{inputText:e},`type ${JSON.stringify(e)}`),console.log(` typed: ${JSON.stringify(e)}`);break}case"key":{let e=a[1];e||(console.error(S("key","<name>")),process.exit(1)),await ue(l,"key"),await l.send({type:"keyboard",action:"press",text:e}),await L("inspect key",{pressKey:e},`key ${e}`),console.log(` pressed: ${e}`);break}case"key-sequence":{let e=a.slice(1);e.length===0&&(console.error(S("key-sequence","<key> [<key> ...]")),process.exit(1)),await ue(l,"key-sequence");for(let t of e)await l.send({type:"keyboard",action:"press",text:t});await L("inspect key-sequence",{pressKey:e.join(" ")},`key-sequence ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"keycode":{let e=a.slice(1);e.length===0&&(console.error(S("keycode","<code> [<code> ...]")),process.exit(1));let t=e.map(r=>({code:r,key:Rt(r)})),s=t.filter(r=>!r.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(r=>r.code).join(", ")}`),process.exit(1)),await ue(l,"keycode");for(let r of t)await l.send({type:"keyboard",action:"press",text:r.key});await L("inspect keycode",{pressKey:t.map(r=>r.key).join(" ")},`keycode ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"dispatch":{let e=a[1];e||(console.error(S("dispatch","<char>")),process.exit(1)),await l.send({type:"keyboard",action:"dispatchKey",text:e}),await L("inspect dispatch",{dispatchKey:e},`dispatch ${JSON.stringify(e)}`),console.log(` dispatched: ${e}`);break}case"dismiss":{await l.send({type:"keyboard",action:"dismiss"}),await L("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let e=Number(a[1]),t=Number(a[2]),s=se(o);if(s){let p=await ce(l,s);p||(console.error(` not found: ${s.value}`),s.mode==="testid"&&U("wait-selector-for-missing-testid",s.value),process.exit(1)),e=p.x,t=p.y}let r=a[3]?Number(a[3]):80;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(S("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let n=Math.max(0,Math.round(r)),m=await l.send({type:"evaluate",code:`(async () => {
498
502
  const interact = window.__sootsimInteract
499
503
  if (interact?.doubleTap) {
500
504
  return {
@@ -522,13 +526,13 @@ ${s}
522
526
  if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
523
527
  const value = await interact.longPress(${e}, ${t}, ${Math.max(0,Math.round(r))})
524
528
  return { ok: !!value, value }
525
- })()`});n?.ok&&await L("inspect long-press",{tapAtCoords:{x:e,y:t}},`long-press @${e},${t}`),console.log(JSON.stringify(n,null,2));break}case"touch":{let e=a[1],t=Number(a[2]),s=Number(a[3]),r=a[4]?Number(a[4]):999,n=e==="down"?"touchDown":e==="move"?"touchMove":e==="up"?"touchUp":e==="cancel"?"touchCancel":null;n||(console.error(S("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),e!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(S("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let m=e==="down"?"tap":e==="move"?"move":null,p=m&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${m}', x: ${t}, y: ${s} } }));`:"",h=await l.send({type:"evaluate",code:`(async () => {
529
+ })()`});n?.ok&&await L("inspect long-press",{tapAtCoords:{x:e,y:t}},`long-press @${e},${t}`),console.log(JSON.stringify(n,null,2));break}case"touch":{let e=a[1],t=Number(a[2]),s=Number(a[3]),r=a[4]?Number(a[4]):999,n=e==="down"?"touchDown":e==="move"?"touchMove":e==="up"?"touchUp":e==="cancel"?"touchCancel":null;n||(console.error(S("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),e!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(S("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let m=e==="down"?"tap":e==="move"?"move":null,p=m&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${m}', x: ${t}, y: ${s} } }));`:"",b=await l.send({type:"evaluate",code:`(async () => {
526
530
  ${p}
527
531
  const interact = window.__sootsimInteract
528
532
  if (!interact?.${n}) return { ok: false, reason: 'no interact.${n}' }
529
533
  const value = ${e==="cancel"?`await interact.${n}(${Math.max(1,Math.round(r))})`:`await interact.${n}(${t}, ${s}, ${Math.max(1,Math.round(r))})`}
530
534
  return { ok: !!value, value }
531
- })()`});h?.ok&&e!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${e} @${t},${s}`),console.log(JSON.stringify(h,null,2));break}case"gesture":{let e=a[1],t=a[2]?Number(a[2]):220;(!e||!Number.isFinite(t))&&(console.error(S("gesture","<preset> [durationMs]")),process.exit(1));let s=await l.send({type:"evaluate",code:`(async () => {
535
+ })()`});b?.ok&&e!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${e} @${t},${s}`),console.log(JSON.stringify(b,null,2));break}case"gesture":{let e=a[1],t=a[2]?Number(a[2]):220;(!e||!Number.isFinite(t))&&(console.error(S("gesture","<preset> [durationMs]")),process.exit(1));let s=await l.send({type:"evaluate",code:`(async () => {
532
536
  const spec = globalThis.__sootsimDeviceSpec || {}
533
537
  return {
534
538
  width: spec.width || window.innerWidth || 393,
@@ -536,7 +540,7 @@ ${s}
536
540
  statusBarHeight: spec.statusBarHeight || 0,
537
541
  homeIndicatorHeight: spec.homeIndicatorHeight || 0,
538
542
  }
539
- })()`}),r=Number(s?.width)||393,n=Number(s?.height)||852,m=Number(s?.statusBarHeight)||0,p=Number(s?.homeIndicatorHeight)||0,h=Math.round(r/2),f=Math.round(n/2),w=Math.max(24,m+18),O=Math.max(24,p+18),B=18,N=Math.min(220,Math.round(n*.24)),M=Math.min(180,Math.round(r*.32)),F=h,W=f,g=h,T=f;switch(e){case"scroll-up":W=f+Math.round(N/2),T=f-Math.round(N/2);break;case"scroll-down":W=f-Math.round(N/2),T=f+Math.round(N/2);break;case"scroll-left":F=h+Math.round(M/2),g=h-Math.round(M/2);break;case"scroll-right":F=h-Math.round(M/2),g=h+Math.round(M/2);break;case"swipe-from-left-edge":F=B,W=f,g=Math.min(r-B,B+M);break;case"swipe-from-right-edge":F=r-B,W=f,g=Math.max(B,r-B-M);break;case"swipe-from-top-edge":F=h,W=w,T=Math.min(n-O,w+N);break;case"swipe-from-bottom-edge":F=h,W=n-O,T=Math.max(w,n-O-N);break;default:console.error(` unknown gesture preset: ${e}`),process.exit(1)}let _=Math.max(8,Math.round(t/16)),P=Math.max(1,Math.round(t/_)),re=await l.send({type:"evaluate",code:`(async () => {
543
+ })()`}),r=Number(s?.width)||393,n=Number(s?.height)||852,m=Number(s?.statusBarHeight)||0,p=Number(s?.homeIndicatorHeight)||0,b=Math.round(r/2),f=Math.round(n/2),w=Math.max(24,m+18),O=Math.max(24,p+18),B=18,N=Math.min(220,Math.round(n*.24)),M=Math.min(180,Math.round(r*.32)),F=b,W=f,g=b,T=f;switch(e){case"scroll-up":W=f+Math.round(N/2),T=f-Math.round(N/2);break;case"scroll-down":W=f-Math.round(N/2),T=f+Math.round(N/2);break;case"scroll-left":F=b+Math.round(M/2),g=b-Math.round(M/2);break;case"scroll-right":F=b-Math.round(M/2),g=b+Math.round(M/2);break;case"swipe-from-left-edge":F=B,W=f,g=Math.min(r-B,B+M);break;case"swipe-from-right-edge":F=r-B,W=f,g=Math.max(B,r-B-M);break;case"swipe-from-top-edge":F=b,W=w,T=Math.min(n-O,w+N);break;case"swipe-from-bottom-edge":F=b,W=n-O,T=Math.max(w,n-O-N);break;default:console.error(` unknown gesture preset: ${e}`),process.exit(1)}let _=Math.max(8,Math.round(t/16)),P=Math.max(1,Math.round(t/_)),re=await l.send({type:"evaluate",code:`(async () => {
540
544
  const interact = window.__sootsimInteract
541
545
  if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
542
546
  const value = await interact.drag(${F}, ${W}, ${g}, ${T}, ${_}, ${P})
@@ -577,7 +581,7 @@ ${s}
577
581
  ${y("state")} scroll feed
578
582
  ${y("state")} scroll-hit 360 420
579
583
  ${y("state")} hit 200 720
580
- `);break}let t;switch(e){case"shell":t=await V(l,500);break;case"worker":t=await ve(l,"__sootsimRenderHost.queryStats");break;case"ownership":t=await l.send({type:"evaluate",code:`(() => {
584
+ `);break}let t;switch(e){case"shell":t=await V(l,500);break;case"worker":t=await ke(l,"__sootsimRenderHost.queryStats");break;case"ownership":t=await l.send({type:"evaluate",code:`(() => {
581
585
  const h = window.__sootsimRenderHost
582
586
  if (!h || typeof h.getOwnershipSnapshot !== 'function') {
583
587
  return { error: 'getOwnershipSnapshot not available' }
@@ -632,7 +636,7 @@ ${s}
632
636
  ${y("shell")} open-card clock 800
633
637
  ${y("shell")} appearance dark
634
638
  ${y("shell")} lock
635
- `);break}let t=e==="launch"||e==="open-card"||e==="home"||e==="switcher",s=e==="launch"||e==="open-card"?a[3]:a[2],r=s?Number(s):350;t&&(!Number.isFinite(r)||r<0)&&(console.error(S("shell",e==="launch"||e==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let n=!1,m=!1,p=null,h=o.includes("--clear-state");if(e==="launch"){let f=a[2];f||(console.error(S("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),h&&await l.send({type:"evaluate",code:Te}),n=!!await te(l,"launchApp",r,f),{settled:m,state:p}=await de(l,Math.round(r),w=>!!w&&w.state==="app"&&w.activeApp===f&&w.showSwitcher===!1&&w.switcherPhase==="idle"&&typeof w.launchProgress=="number"&&w.launchProgress>=.98),n&&await L("inspect shell launch",h?{launchApp:{clearState:!0}}:{launchApp:{}},h?"launch app (clear state)":"launch app")}else if(e==="home")n=!!await te(l,"goHome",r),{settled:m,state:p}=await de(l,Math.round(r),f=>!!f&&f.state==="home"&&f.activeApp==null&&f.showSwitcher===!1&&f.switcherPhase==="idle"&&typeof f.launchProgress=="number"&&f.launchProgress>=.98);else if(e==="switcher")n=!!await te(l,"openSwitcher",r),{settled:m,state:p}=await de(l,Math.round(r),f=>!!f&&f.state==="app"&&f.showSwitcher===!0&&f.switcherPhase==="idle"&&typeof f.zoomLevel=="number"&&Math.abs(f.zoomLevel)<=.02&&typeof f.horizontalZoom=="number"&&Math.abs(f.horizontalZoom)<=.02),m&&(await Y(Pt),p=await V(l));else if(e==="open-card"){let f=a[2];f||(console.error(S("shell","open-card <appId> [settleMs]")),process.exit(1)),n=!!await te(l,"openSwitcherCard",r,f),{settled:m,state:p}=await de(l,Math.round(r),w=>!!w&&w.state==="app"&&w.activeApp===f&&w.showSwitcher===!1&&w.switcherPhase==="idle"&&typeof w.zoomLevel=="number"&&w.zoomLevel>=.98&&typeof w.horizontalZoom=="number"&&w.horizontalZoom>=.98),n&&await L("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(e==="appearance"){let f=a[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(S("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let w=await tt(l,"appearance",f);n=!!w?.ok,p={appearance:w}}else if(e==="lock"||e==="shake"){let f=await tt(l,e);n=!!f?.ok,p={[e]:f}}else console.error(` unknown shell subcommand: ${e}`),process.exit(1);console.log(JSON.stringify({ok:n,settled:m,state:p},null,2));break}case"url":{await Ke(l,{args:d});break}case"reload":{let s=!1,r=!1;try{await l.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await l.send({type:"evaluate",code:`;(() => {
639
+ `);break}let t=e==="launch"||e==="open-card"||e==="home"||e==="switcher",s=e==="launch"||e==="open-card"?a[3]:a[2],r=s?Number(s):350;t&&(!Number.isFinite(r)||r<0)&&(console.error(S("shell",e==="launch"||e==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let n=!1,m=!1,p=null,b=o.includes("--clear-state");if(e==="launch"){let f=a[2];f||(console.error(S("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),b&&await l.send({type:"evaluate",code:Te}),n=!!await te(l,"launchApp",r,f),{settled:m,state:p}=await de(l,Math.round(r),w=>!!w&&w.state==="app"&&w.activeApp===f&&w.showSwitcher===!1&&w.switcherPhase==="idle"&&typeof w.launchProgress=="number"&&w.launchProgress>=.98),n&&await L("inspect shell launch",b?{launchApp:{clearState:!0}}:{launchApp:{}},b?"launch app (clear state)":"launch app")}else if(e==="home")n=!!await te(l,"goHome",r),{settled:m,state:p}=await de(l,Math.round(r),f=>!!f&&f.state==="home"&&f.activeApp==null&&f.showSwitcher===!1&&f.switcherPhase==="idle"&&typeof f.launchProgress=="number"&&f.launchProgress>=.98);else if(e==="switcher")n=!!await te(l,"openSwitcher",r),{settled:m,state:p}=await de(l,Math.round(r),f=>!!f&&f.state==="app"&&f.showSwitcher===!0&&f.switcherPhase==="idle"&&typeof f.zoomLevel=="number"&&Math.abs(f.zoomLevel)<=.02&&typeof f.horizontalZoom=="number"&&Math.abs(f.horizontalZoom)<=.02),m&&(await Y(Ot),p=await V(l));else if(e==="open-card"){let f=a[2];f||(console.error(S("shell","open-card <appId> [settleMs]")),process.exit(1)),n=!!await te(l,"openSwitcherCard",r,f),{settled:m,state:p}=await de(l,Math.round(r),w=>!!w&&w.state==="app"&&w.activeApp===f&&w.showSwitcher===!1&&w.switcherPhase==="idle"&&typeof w.zoomLevel=="number"&&w.zoomLevel>=.98&&typeof w.horizontalZoom=="number"&&w.horizontalZoom>=.98),n&&await L("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(e==="appearance"){let f=a[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(S("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let w=await ot(l,"appearance",f);n=!!w?.ok,p={appearance:w}}else if(e==="lock"||e==="shake"){let f=await ot(l,e);n=!!f?.ok,p={[e]:f}}else console.error(` unknown shell subcommand: ${e}`),process.exit(1);console.log(JSON.stringify({ok:n,settled:m,state:p},null,2));break}case"url":{await Ue(l,{args:d});break}case"reload":{let s=!1,r=!1;try{await l.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await l.send({type:"evaluate",code:`;(() => {
636
640
  const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
637
641
  if (typeof reloadExternalApp === 'function') {
638
642
  reloadExternalApp()
@@ -640,9 +644,9 @@ ${s}
640
644
  }
641
645
  window.location.reload()
642
646
  return { kind: 'page' }
643
- })()`});r=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let n=l,m=null;if(r)m=await fe(l,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Y(300);let p=await Fe(A,j,v,{timeoutMs:1e4});p?(n=p,m=await fe(p,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),n=null)}if(m)if(m.ready){let p=m.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${m.elapsedMs}ms: ${m.nodes} nodes${p}`)}else m.source==="error-bail"?console.log(` \u26A0 reload bailed after ${m.elapsedMs}ms: ${m.errors} console error(s), ready signal never fired`):console.log(` \u26A0 reload timed out after ${m.elapsedMs}ms (${m.nodes} nodes, ${m.errors} errors)`);if(n)try{let p=await n.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(n!==l&&n.close(),Array.isArray(p)&&p.length>0){console.log(`
647
+ })()`});r=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let n=l,m=null;if(r)m=await fe(l,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Y(300);let p=await Fe(A,j,k,{timeoutMs:1e4});p?(n=p,m=await fe(p,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),n=null)}if(m)if(m.ready){let p=m.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${m.elapsedMs}ms: ${m.nodes} nodes${p}`)}else m.source==="error-bail"?console.log(` \u26A0 reload bailed after ${m.elapsedMs}ms: ${m.errors} console error(s), ready signal never fired`):console.log(` \u26A0 reload timed out after ${m.elapsedMs}ms (${m.nodes} nodes, ${m.errors} errors)`);if(n)try{let p=await n.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(n!==l&&n.close(),Array.isArray(p)&&p.length>0){console.log(`
644
648
  \u26A0 ${p.length} error(s) during mount:
645
- `);for(let h of p){let f=h.args.map(w=>typeof w=="object"?JSON.stringify(w):w).join(" ");if(console.log(` ${f}`),h.stack){let w=h.stack.split(`
649
+ `);for(let b of p){let f=b.args.map(w=>typeof w=="object"?JSON.stringify(w):w).join(" ");if(console.log(` ${f}`),b.stack){let w=b.stack.split(`
646
650
  `).slice(0,2);for(let O of w)console.log(` ${O.trim()}`)}}}}catch{}m&&!m.ready&&(process.exitCode=1);break}case"eval":case"js":{let e=a.slice(1).join(" ");e||(console.error(S("js","<javascript>")),console.error(""),console.error(" runs the snippet in the engine realm. SootSim is the"),console.error(" canonical state surface \u2014 reach into it directly."),console.error(""),console.error(" examples:"),console.error(` ${y("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${y("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${y("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${y("js")} SootSim.state.root.children.length`),process.exit(1));let t=e;t.startsWith("(async")||(t=`(async () => ${t})()`);let s=await l.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let r=e.toLowerCase(),n=[];(r.includes("sootsim:gohome")||r.includes("gohome"))&&n.push("sootsim shell home"),(r.includes("sootsim:appswitcher")||r.includes("appswitcher"))&&n.push("sootsim shell switcher"),(r.includes("keyboard.isvisible")||r.includes("keyboard.getmode"))&&n.push("sootsim debug state keyboard"),r.includes("interact.tap")&&n.push("sootsim do tap <x> <y>"),r.includes("keyboard.type")&&n.push("sootsim do type <text>"),(r.includes("keyboard.press")||r.includes("keyboard.dispatchkey"))&&n.push("sootsim do key <name>"),r.includes("keyboard.dismiss")&&n.push("sootsim do dismiss"),r.includes("dumptree")&&n.push("sootsim get tree"),r.includes("dumpaccessibilitytree")&&n.push("sootsim get a11y"),r.includes("getnodecount")&&n.push("sootsim get count"),r.includes("findbytext")&&n.push("sootsim find <text>"),(r.includes("findbytestid")||r.includes("findbyid"))&&n.push("sootsim find --testid <id>"),r.includes("document.hidden")&&n.push("sootsim debug state keyboard (includes tab health)"),n.length>0&&U("prefer-cli-over-eval",n);break}case"globals":{let e=await l.send({type:"evaluate",code:`(async () => {
647
651
  const globals = {}
648
652
 
@@ -681,7 +685,7 @@ ${s}
681
685
 
682
686
  return globals
683
687
  })()`});console.log(` sootsim JS API:
684
- `);for(let[t,s]of Object.entries(e)){console.log(` ${t}:`);for(let r of s)console.log(` .${r}`);console.log("")}console.log(` use: ${y("js")} <expression>`),console.log(` example: ${y("js")} test.findByText("Sign in")`);break}case"describe":{await Re({bridge:l,args:o,positional:a});break}case"perf":{let e=a[1];if(!e||e==="--help"||e==="-h"){console.log(`
688
+ `);for(let[t,s]of Object.entries(e)){console.log(` ${t}:`);for(let r of s)console.log(` .${r}`);console.log("")}console.log(` use: ${y("js")} <expression>`),console.log(` example: ${y("js")} test.findByText("Sign in")`);break}case"describe":{await Ce({bridge:l,args:o,positional:a});break}case"perf":{let e=a[1];if(!e||e==="--help"||e==="-h"){console.log(`
685
689
  ${y("perf")} \u2014 performance profiling
686
690
 
687
691
  subcommands:
@@ -874,7 +878,7 @@ ${s}
874
878
  mode: 'main-thread',
875
879
  frames: (stats.recentFrames || []).slice(-${t}),
876
880
  }
877
- })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let n=Array.isArray(s.samples)?s.samples:[];if(n.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` last ${n.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[m,p,h,f,w,O,B]of n)console.log(` ${p.toFixed(2).padStart(7)} ${h.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${B.toFixed(2).padStart(7)} ${String(m).padStart(5)}`);console.log(""),be(n.map(m=>m[1])),s.live&&console.log(" sampling continues");break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` last ${r.length} frame times (ms):`),console.log(` ${r.map(n=>n.toFixed(2)).join(", ")}`),be(r);break}case"worst":{let t=a[2]?Number(a[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await l.send({type:"evaluate",code:`(async () => {
881
+ })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let n=Array.isArray(s.samples)?s.samples:[];if(n.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` last ${n.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[m,p,b,f,w,O,B]of n)console.log(` ${p.toFixed(2).padStart(7)} ${b.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${B.toFixed(2).padStart(7)} ${String(m).padStart(5)}`);console.log(""),he(n.map(m=>m[1])),s.live&&console.log(" sampling continues");break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` last ${r.length} frame times (ms):`),console.log(` ${r.map(n=>n.toFixed(2)).join(", ")}`),he(r);break}case"worst":{let t=a[2]?Number(a[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await l.send({type:"evaluate",code:`(async () => {
878
882
  if (window.__sootsimRenderHost) {
879
883
  const session = window.${G} || {}
880
884
  if (session.active) {
@@ -916,7 +920,7 @@ ${s}
916
920
  mode: 'main-thread',
917
921
  frames: recent.slice().sort((a, b) => b - a).slice(0, ${t}),
918
922
  }
919
- })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let n=Array.isArray(s.samples)?s.samples:[];if(n.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` worst ${n.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[m,p,h,f,w,O,B]of n)console.log(` ${p.toFixed(2).padStart(7)} ${h.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${B.toFixed(2).padStart(7)} ${String(m).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` worst ${r.length} frame times (ms):`),console.log(` ${r.map(n=>n.toFixed(2)).join(", ")}`);break}case"transition":{let t=a[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
923
+ })()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let n=Array.isArray(s.samples)?s.samples:[];if(n.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` worst ${n.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[m,p,b,f,w,O,B]of n)console.log(` ${p.toFixed(2).padStart(7)} ${b.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${B.toFixed(2).padStart(7)} ${String(m).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` worst ${r.length} frame times (ms):`),console.log(` ${r.map(n=>n.toFixed(2)).join(", ")}`);break}case"transition":{let t=a[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
920
924
  ${y("perf")} transition <event> \u2014 profile a shell transition
921
925
 
922
926
  events:
@@ -1006,25 +1010,25 @@ ${s}
1006
1010
  p50: ${n.p50.toFixed(2)}ms
1007
1011
  p95: ${n.p95.toFixed(2)}ms
1008
1012
  p99: ${n.p99.toFixed(2)}ms
1009
- jank: ${n.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(n.samples)&&n.samples.length>0&&(console.log(""),be(n.samples.map(h=>h[1])));break}default:console.error(` unknown perf subcommand: ${e}`),process.exit(1)}break}case"errors":{let e=a[1];if(e==="clear"){await l.send({type:"evaluate",code:'window.__sootsimConsole?.clear(); "cleared"'}),E(d)?C({cleared:!0}):console.log(" error buffer cleared");break}let t=e?Number(e):20,s=await l.send({type:"evaluate",code:`window.__sootsimConsole?.getErrors(${t}) || []`}),r=Array.isArray(s)?s:[];if(E(d)){C(r);break}if(r.length===0){console.log(" no errors captured");break}console.log(` ${r.length} error(s):
1010
- `);for(let n of r){let m=new Date(n.timestamp).toLocaleTimeString(),p=n.args.map(h=>typeof h=="object"?JSON.stringify(h):h).join(" ");if(console.log(` [${m}] ${p}`),n.stack){let h=n.stack.split(`
1011
- `).slice(0,3);for(let f of h)console.log(` ${f.trim()}`)}}break}case"warnings":{let e=a[1]?Number(a[1]):20,t=await l.send({type:"evaluate",code:`window.__sootsimConsole?.getWarnings(${e}) || []`}),s=Array.isArray(t)?t:[];if(E(d)){C(s);break}if(s.length===0){console.log(" no warnings captured");break}console.log(` ${s.length} warning(s):
1013
+ jank: ${n.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(n.samples)&&n.samples.length>0&&(console.log(""),he(n.samples.map(b=>b[1])));break}default:console.error(` unknown perf subcommand: ${e}`),process.exit(1)}break}case"errors":{let e=a[1];if(e==="clear"){await l.send({type:"evaluate",code:'window.__sootsimConsole?.clear(); "cleared"'}),E(d)?C({cleared:!0}):console.log(" error buffer cleared");break}let t=e?Number(e):20,s=await l.send({type:"evaluate",code:`window.__sootsimConsole?.getErrors(${t}) || []`}),r=Array.isArray(s)?s:[];if(E(d)){C(r);break}if(r.length===0){console.log(" no errors captured");break}console.log(` ${r.length} error(s):
1014
+ `);for(let n of r){let m=new Date(n.timestamp).toLocaleTimeString(),p=n.args.map(b=>typeof b=="object"?JSON.stringify(b):b).join(" ");if(console.log(` [${m}] ${p}`),n.stack){let b=n.stack.split(`
1015
+ `).slice(0,3);for(let f of b)console.log(` ${f.trim()}`)}}break}case"warnings":{let e=a[1]?Number(a[1]):20,t=await l.send({type:"evaluate",code:`window.__sootsimConsole?.getWarnings(${e}) || []`}),s=Array.isArray(t)?t:[];if(E(d)){C(s);break}if(s.length===0){console.log(" no warnings captured");break}console.log(` ${s.length} warning(s):
1012
1016
  `);for(let r of s){let n=new Date(r.timestamp).toLocaleTimeString(),m=r.args.map(p=>typeof p=="object"?JSON.stringify(p):p).join(" ");console.log(` [${n}] ${m}`)}break}case"animations":{let e=await z(l,"listAnimations")??[];if(o.includes("--json")){console.log(JSON.stringify(e,null,2));break}if(e.length===0){console.log(" no active animations");break}console.log(` ${e.length} active animation(s):
1013
- `);for(let t of e){let s=String(t.kind).padEnd(6),r=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,n=Number(t.current??0).toFixed(2),m=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,h=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${r.padEnd(14)} cur=${n.padEnd(7)} ${m.padStart(4)} ${p}${h}${f}`)}break}case"animation":{let e=a[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${y("animation")} <id>`),process.exit(1));let t=Number(e);Number.isFinite(t)||(console.error(` invalid id: ${e}`),process.exit(1));let s=await z(l,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let e=a[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${y("stop-animation")} <id|all>`),process.exit(1));let t=e==="all"?"all":Number(e);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${e}`),process.exit(1));let s=await z(l,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let e=a[1];if(e==="clear"){await z(l,"clearRequests"),E(d)?C({cleared:!0}):console.log(" request buffer cleared");break}let t=e==="all",s=t?a[2]:e,r=s?Number(s):20,n=t?await z(l,"getRequests",r):await z(l,"getFailedRequests",r),m=Array.isArray(n)?n:[];if(E(d)){C(m);break}if(m.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${m.length} ${t?"request(s)":"failed request(s)"}:
1014
- `);for(let p of m){let h=new Date(p.timestamp).toLocaleTimeString();console.log(` [${h}] ${q(p)}`),p.responseBody?console.log(` ${p.responseBody}`):p.error&&console.log(` ${p.error}`)}break}case"network":{let e=a[1],t=null,s=null,r=!1,n=!1,m=!1;for(let N=0;N<d.length;N++){let M=d[N];if(M==="--filter")t=d[N+1]??null,N++;else if(M==="--limit"){let F=Number(d[N+1]);Number.isFinite(F)&&(s=F),N++}else M==="--failed"?r=!0:M==="--tail"||M==="-f"?n=!0:M==="--json"&&(m=!0)}if(e==="clear"){await l.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(e==="get"){let N=a[2];N||(console.error(" usage: sootsim network get <id>"),process.exit(1));let M=await l.send({type:"evaluate",code:`(() => {
1017
+ `);for(let t of e){let s=String(t.kind).padEnd(6),r=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,n=Number(t.current??0).toFixed(2),m=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,b=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${r.padEnd(14)} cur=${n.padEnd(7)} ${m.padStart(4)} ${p}${b}${f}`)}break}case"animation":{let e=a[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${y("animation")} <id>`),process.exit(1));let t=Number(e);Number.isFinite(t)||(console.error(` invalid id: ${e}`),process.exit(1));let s=await z(l,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let e=a[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${y("stop-animation")} <id|all>`),process.exit(1));let t=e==="all"?"all":Number(e);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${e}`),process.exit(1));let s=await z(l,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let e=a[1];if(e==="clear"){await z(l,"clearRequests"),E(d)?C({cleared:!0}):console.log(" request buffer cleared");break}let t=e==="all",s=t?a[2]:e,r=s?Number(s):20,n=t?await z(l,"getRequests",r):await z(l,"getFailedRequests",r),m=Array.isArray(n)?n:[];if(E(d)){C(m);break}if(m.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${m.length} ${t?"request(s)":"failed request(s)"}:
1018
+ `);for(let p of m){let b=new Date(p.timestamp).toLocaleTimeString();console.log(` [${b}] ${q(p)}`),p.responseBody?console.log(` ${p.responseBody}`):p.error&&console.log(` ${p.error}`)}break}case"network":{let e=a[1],t=null,s=null,r=!1,n=!1,m=!1;for(let N=0;N<d.length;N++){let M=d[N];if(M==="--filter")t=d[N+1]??null,N++;else if(M==="--limit"){let F=Number(d[N+1]);Number.isFinite(F)&&(s=F),N++}else M==="--failed"?r=!0:M==="--tail"||M==="-f"?n=!0:M==="--json"&&(m=!0)}if(e==="clear"){await l.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(e==="get"){let N=a[2];N||(console.error(" usage: sootsim network get <id>"),process.exit(1));let M=await l.send({type:"evaluate",code:`(() => {
1015
1019
  const obs = window.__sootsimObservability;
1016
1020
  if (!obs) return null;
1017
1021
  return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(N)}) || null;
1018
- })()`});M||(console.error(` no entry with id ${N}`),process.exit(1)),m?console.log(JSON.stringify(M,null,2)):It(M);break}let p=s??(n?200:e?Number(e):20);Number.isFinite(p)||(console.error(` invalid limit: ${e}`),process.exit(1));let h=async()=>{let N=await l.send({type:"evaluate",code:`(() => {
1022
+ })()`});M||(console.error(` no entry with id ${N}`),process.exit(1)),m?console.log(JSON.stringify(M,null,2)):Ft(M);break}let p=s??(n?200:e?Number(e):20);Number.isFinite(p)||(console.error(` invalid limit: ${e}`),process.exit(1));let b=async()=>{let N=await l.send({type:"evaluate",code:`(() => {
1019
1023
  const obs = window.__sootsimObservability;
1020
1024
  if (!obs) return { ok: false };
1021
1025
  return { ok: true, entries: obs.network.getSnapshot() };
1022
- })()`});if(!N||!N.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return N.entries??[]},f=N=>{let M=N;if(r&&(M=M.filter(F=>!!F.error||F.status!=null&&F.status>=400)),t){let F=t.toLowerCase();M=M.filter(W=>(W.displayUrl||W.url).toLowerCase().includes(F))}return M};if(!n){let N=await h(),M=f(N).slice(-p);if(m){console.log(JSON.stringify(M,null,2));break}if(M.length===0){console.log(N.length===0?" no network requests captured":" no matching requests");break}console.log(` ${M.length} request(s):
1023
- `);for(let F of M)Ve(F);break}console.log(` tailing network (ctrl-c to stop)...
1024
- `);let w=new Set,O=!0,B=()=>{O=!1};process.on("SIGINT",B);try{for(;O;){let N=await h(),M=f(N);for(let F of M)F.durationMs!=null&&(w.has(F.id)||(w.add(F.id),m?console.log(JSON.stringify(F)):Ve(F)));await Y(250)}}finally{process.off("SIGINT",B)}break}case"logs":{let e=a[1],t=null,s=null,r=null,n=!1,m=!1,p=!1;for(let g=0;g<d.length;g++){let T=d[g];if(T==="--filter")t=d[g+1]??null,g++;else if(T==="--limit"){let _=Number(d[g+1]);Number.isFinite(_)&&(s=_),g++}else T==="--level"?(r=d[g+1]??null,g++):T==="--tail"||T==="-f"?n=!0:T==="--json"?m=!0:(T==="--internal"||T==="--all")&&(p=!0)}let h=r?new Set(r.split(",").map(g=>g.trim()).filter(g=>g==="log"||g==="info"||g==="warn"||g==="error"||g==="debug")):null;if(e==="clear"){await l.send({type:"evaluate",code:'window.__sootsimObservability?.logs.clear(); "cleared"'}),console.log(" log buffer cleared");break}let f=!m&&process.stdout.isTTY===!0,w=s??(n?500:e?Number(e):50);Number.isFinite(w)||(console.error(` invalid limit: ${e}`),process.exit(1));let O=async()=>{let g=await l.send({type:"evaluate",code:`(() => {
1026
+ })()`});if(!N||!N.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return N.entries??[]},f=N=>{let M=N;if(r&&(M=M.filter(F=>!!F.error||F.status!=null&&F.status>=400)),t){let F=t.toLowerCase();M=M.filter(W=>(W.displayUrl||W.url).toLowerCase().includes(F))}return M};if(!n){let N=await b(),M=f(N).slice(-p);if(m){console.log(JSON.stringify(M,null,2));break}if(M.length===0){console.log(N.length===0?" no network requests captured":" no matching requests");break}console.log(` ${M.length} request(s):
1027
+ `);for(let F of M)Ze(F);break}console.log(` tailing network (ctrl-c to stop)...
1028
+ `);let w=new Set,O=!0,B=()=>{O=!1};process.on("SIGINT",B);try{for(;O;){let N=await b(),M=f(N);for(let F of M)F.durationMs!=null&&(w.has(F.id)||(w.add(F.id),m?console.log(JSON.stringify(F)):Ze(F)));await Y(250)}}finally{process.off("SIGINT",B)}break}case"logs":{let e=a[1],t=null,s=null,r=null,n=!1,m=!1,p=!1;for(let g=0;g<d.length;g++){let T=d[g];if(T==="--filter")t=d[g+1]??null,g++;else if(T==="--limit"){let _=Number(d[g+1]);Number.isFinite(_)&&(s=_),g++}else T==="--level"?(r=d[g+1]??null,g++):T==="--tail"||T==="-f"?n=!0:T==="--json"?m=!0:(T==="--internal"||T==="--all")&&(p=!0)}let b=r?new Set(r.split(",").map(g=>g.trim()).filter(g=>g==="log"||g==="info"||g==="warn"||g==="error"||g==="debug")):null;if(e==="clear"){await l.send({type:"evaluate",code:'window.__sootsimObservability?.logs.clear(); "cleared"'}),console.log(" log buffer cleared");break}let f=!m&&process.stdout.isTTY===!0,w=s??(n?500:e?Number(e):50);Number.isFinite(w)||(console.error(` invalid limit: ${e}`),process.exit(1));let O=async()=>{let g=await l.send({type:"evaluate",code:`(() => {
1025
1029
  const obs = window.__sootsimObservability;
1026
1030
  if (!obs) return { ok: false };
1027
1031
  return { ok: true, entries: obs.logs.getSnapshot() };
1028
- })()`});if(!g||!g.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return g.entries??[]},B=g=>{let T=g.args[0];return typeof T!="string"?!1:T.startsWith("[sootsim]")},N=g=>{let T=g;if(p||(T=T.filter(_=>!B(_))),h&&(T=T.filter(_=>h.has(_.level))),t){let _=t.toLowerCase();T=T.filter(P=>P.args.join(" ").toLowerCase().includes(_))}return T};if(!n){let g=await O(),T=N(g).slice(-w);if(m){console.log(JSON.stringify(T,null,2));break}if(T.length===0){console.log(g.length===0?" no logs captured":" no matching logs");break}console.log(` ${T.length} log(s):
1029
- `);for(let _ of T)Qe(_,f);break}console.log(` tailing logs (ctrl-c to stop)...
1030
- `);let M=new Set,F=!0,W=()=>{F=!1};process.on("SIGINT",W);try{for(;F;){let g=await O(),T=N(g);for(let _ of T)M.has(_.id)||(M.add(_.id),m?console.log(JSON.stringify(_)):Qe(_,f));await Y(250)}}finally{process.off("SIGINT",W)}break}default:console.error(` unknown subcommand: ${b}`),process.exit(1)}if(H.has(b)&&!o.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await ne(l),!D.has(b)&&!E(d)){let e=await Z();try{await J({counts:e.console})}catch{}try{await x({counts:e.requests})}catch{}}}catch(e){console.error(` ${b??"inspect"} failed: ${e.message}`);try{await Me(l)}catch{}try{await J({includeTail:!0})}catch{}try{await x({includeTail:!0})}catch{}process.exit(1)}finally{l.close()}}export{ss as runInspect};
1032
+ })()`});if(!g||!g.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return g.entries??[]},B=g=>{let T=g.args[0];return typeof T!="string"?!1:T.startsWith("[sootsim]")},N=g=>{let T=g;if(p||(T=T.filter(_=>!B(_))),b&&(T=T.filter(_=>b.has(_.level))),t){let _=t.toLowerCase();T=T.filter(P=>P.args.join(" ").toLowerCase().includes(_))}return T};if(!n){let g=await O(),T=N(g).slice(-w);if(m){console.log(JSON.stringify(T,null,2));break}if(T.length===0){console.log(g.length===0?" no logs captured":" no matching logs");break}console.log(` ${T.length} log(s):
1033
+ `);for(let _ of T)et(_,f);break}console.log(` tailing logs (ctrl-c to stop)...
1034
+ `);let M=new Set,F=!0,W=()=>{F=!1};process.on("SIGINT",W);try{for(;F;){let g=await O(),T=N(g);for(let _ of T)M.has(_.id)||(M.add(_.id),m?console.log(JSON.stringify(_)):et(_,f));await Y(250)}}finally{process.off("SIGINT",W)}break}default:console.error(` unknown subcommand: ${h}`),process.exit(1)}if(H.has(h)&&!o.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await ne(l),!D.has(h)&&!E(d)){let e=await Z();try{await J({counts:e.console})}catch{}try{await x({counts:e.requests})}catch{}}}catch(e){let t=e instanceof Error?e.message:String(e);if(console.error(` ${h??"inspect"} failed: ${t}`),/^no browser connected( with id .+)?$/.test(t))Ae(A);else{try{await Me(l)}catch{}try{await J({includeTail:!0})}catch{}try{await x({includeTail:!0})}catch{}}process.exit(1)}finally{l.close()}}export{rs as runInspect};
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as o}from"./chunk-27P763IZ.js";import"./chunk-VFDRZNPN.js";import"./chunk-IJMYFYDZ.js";import"./chunk-EJLNUMMP.js";import"./chunk-TC6V7YFC.js";import"./chunk-SMVJOWSV.js";import"./chunk-6GGMKFWJ.js";import"./chunk-ZEW3RF5Q.js";import"./chunk-5QIUJNT3.js";import"./chunk-LHDWH7VS.js";async function t(n){console.error(" note: `sootsim install` is now `sootsim setup-repo`. forwarding\u2026\n"),await o(n)}export{t as runInstall};