sootsim 0.1.270 → 0.1.271

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/dist-cli/bin.js +4 -4
  2. package/dist-cli/chunks/{agent-4YXUPSJ2.js → agent-L744OWW2.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-BMJPWHWK.js → agent-wrapper-F7YU7YQY.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-EDRH6ETC.js → app-fonts-AOVWJ64N.js} +2 -2
  5. package/dist-cli/chunks/{assert-CRDV324D.js → assert-VM6WQOSH.js} +2 -2
  6. package/dist-cli/chunks/{auth-WYRQIJEN.js → auth-I73YF2VH.js} +2 -2
  7. package/dist-cli/chunks/beta-FKJVCD4P.js +2 -0
  8. package/dist-cli/chunks/{camera-5TO6IVBP.js → camera-5LP32MN5.js} +2 -2
  9. package/dist-cli/chunks/{chunk-2J3E5TPS.js → chunk-2MAZYB4E.js} +1 -1
  10. package/dist-cli/chunks/{chunk-NTO6SKS5.js → chunk-3PDYKW67.js} +1 -1
  11. package/dist-cli/chunks/{chunk-ZTKDHPA6.js → chunk-4ISBAFYP.js} +2 -2
  12. package/dist-cli/chunks/{chunk-FCMEOOQE.js → chunk-4SRHESEZ.js} +2 -2
  13. package/dist-cli/chunks/{chunk-B5IBLYEO.js → chunk-53YHX2QG.js} +3 -3
  14. package/dist-cli/chunks/{chunk-ABSUFSOH.js → chunk-5PLAZK5V.js} +2 -2
  15. package/dist-cli/chunks/{chunk-SW5HZ5LK.js → chunk-62CTB2NZ.js} +1 -1
  16. package/dist-cli/chunks/{chunk-GAYG7AO4.js → chunk-6GT6YSKU.js} +1 -1
  17. package/dist-cli/chunks/{chunk-4HPWZVBS.js → chunk-7MWXZLC3.js} +1 -1
  18. package/dist-cli/chunks/{chunk-TMWNOQAA.js → chunk-ACZDS4HL.js} +1 -1
  19. package/dist-cli/chunks/{chunk-OUKH6UGN.js → chunk-BSKGIVGK.js} +1 -1
  20. package/dist-cli/chunks/{chunk-M32JVXHU.js → chunk-DDVJQ7KL.js} +1 -1
  21. package/dist-cli/chunks/{chunk-6CI73D3X.js → chunk-DQCYF257.js} +2 -2
  22. package/dist-cli/chunks/{chunk-LHMVSKKD.js → chunk-DVUSIJGM.js} +2 -2
  23. package/dist-cli/chunks/{chunk-M5VURHXD.js → chunk-FLCWG5TT.js} +1 -1
  24. package/dist-cli/chunks/{chunk-DCJXHSIA.js → chunk-GATLQUZD.js} +2 -2
  25. package/dist-cli/chunks/{chunk-3ZOF2BTJ.js → chunk-I5GCWNIJ.js} +1 -1
  26. package/dist-cli/chunks/{chunk-UPRCATUH.js → chunk-ILNCM267.js} +2 -2
  27. package/dist-cli/chunks/chunk-JTQM46FY.js +1 -0
  28. package/dist-cli/chunks/{chunk-5IHDZOMR.js → chunk-KDQDKEGD.js} +1 -1
  29. package/dist-cli/chunks/{chunk-FNBFRG64.js → chunk-KNBKEQMZ.js} +1 -1
  30. package/dist-cli/chunks/{chunk-SLR3HWMB.js → chunk-KQTMW2VR.js} +2 -2
  31. package/dist-cli/chunks/{chunk-6JLIPPNB.js → chunk-MP55R5YC.js} +1 -1
  32. package/dist-cli/chunks/{chunk-HWGKGIWE.js → chunk-MVXVG2BX.js} +2 -2
  33. package/dist-cli/chunks/{chunk-TZH4VH32.js → chunk-MY2BVCQF.js} +3 -3
  34. package/dist-cli/chunks/{chunk-74HIBIJQ.js → chunk-NXJIRSYB.js} +1 -1
  35. package/dist-cli/chunks/{chunk-MD24VVKT.js → chunk-OFKDXQMY.js} +2 -2
  36. package/dist-cli/chunks/chunk-OFYXCIJ4.js +1 -0
  37. package/dist-cli/chunks/{chunk-GQDQO3KU.js → chunk-QPJHNF2H.js} +2 -2
  38. package/dist-cli/chunks/{chunk-557IYHPC.js → chunk-QSUJV6FY.js} +1 -1
  39. package/dist-cli/chunks/{chunk-3VIMSXQZ.js → chunk-RBRFATPJ.js} +2 -2
  40. package/dist-cli/chunks/chunk-RVATR53A.js +2 -0
  41. package/dist-cli/chunks/{chunk-AMVYE3F4.js → chunk-SJRK4IQV.js} +2 -2
  42. package/dist-cli/chunks/{chunk-YKK2QUGO.js → chunk-TIAKOUSI.js} +1 -1
  43. package/dist-cli/chunks/{chunk-44ISBOEK.js → chunk-TQK4ONSC.js} +3 -3
  44. package/dist-cli/chunks/{chunk-ERXCR7NU.js → chunk-UTYJQ65T.js} +2 -2
  45. package/dist-cli/chunks/{chunk-AMA3YGJ5.js → chunk-V6JB3XB7.js} +2 -2
  46. package/dist-cli/chunks/{chunk-IIXRM6BB.js → chunk-VI3WG25A.js} +2 -2
  47. package/dist-cli/chunks/{chunk-SDKIUJUO.js → chunk-WIYFHKRE.js} +2 -2
  48. package/dist-cli/chunks/{chunk-FHPXOPMC.js → chunk-WOLESEXG.js} +2 -2
  49. package/dist-cli/chunks/{chunk-AG563BSO.js → chunk-WU3TJDWA.js} +2 -2
  50. package/dist-cli/chunks/{chunk-MYBY7OHL.js → chunk-YGEZZQ34.js} +1 -1
  51. package/dist-cli/chunks/{chunk-TLNGREAA.js → chunk-Z6WIJUFD.js} +2 -2
  52. package/dist-cli/chunks/{chunk-TIONGRTA.js → chunk-ZBGUJKMS.js} +18 -18
  53. package/dist-cli/chunks/cli-version-YLTMQC3T.js +2 -0
  54. package/dist-cli/chunks/{compat-IZEDAAUW.js → compat-GTD44O52.js} +3 -3
  55. package/dist-cli/chunks/{config-I4CXZ6M7.js → config-75QCBOYK.js} +2 -2
  56. package/dist-cli/chunks/{control-DVF7UL5D.js → control-MOMQFZYG.js} +2 -2
  57. package/dist-cli/chunks/daemon-MCX26DKV.js +2 -0
  58. package/dist-cli/chunks/{debug-5X2F2WRP.js → debug-MOQUSHCC.js} +3 -3
  59. package/dist-cli/chunks/{desktop-JHEYQZGF.js → desktop-5TQB3QBP.js} +3 -3
  60. package/dist-cli/chunks/{detox-W64UENQG.js → detox-EJIFEK7G.js} +2 -2
  61. package/dist-cli/chunks/{device-ZBSW2EHS.js → device-7XUADG3E.js} +2 -2
  62. package/dist-cli/chunks/{diagnose-WER4X3P5.js → diagnose-5DEHAEPK.js} +2 -2
  63. package/dist-cli/chunks/drivers-6QDWYOP5.js +2 -0
  64. package/dist-cli/chunks/{film-TIXNUTR6.js → film-AZXWITDW.js} +3 -3
  65. package/dist-cli/chunks/flow-SBH3AZJ3.js +2 -0
  66. package/dist-cli/chunks/help-SLGCB5J2.js +2 -0
  67. package/dist-cli/chunks/{hidden-runtime-alias-R3JH3INM.js → hidden-runtime-alias-5FXUVO7I.js} +2 -2
  68. package/dist-cli/chunks/{home-paths-CNNARPCT.js → home-paths-O6TNVGMZ.js} +2 -2
  69. package/dist-cli/chunks/inspect-NMJDGO37.js +2 -0
  70. package/dist-cli/chunks/install-desktop-PO67KHJF.js +2 -0
  71. package/dist-cli/chunks/{login-6NCCZ3CZ.js → login-JZQBHZ6C.js} +4 -4
  72. package/dist-cli/chunks/{logout-C4VKXUH4.js → logout-W3ROHISE.js} +2 -2
  73. package/dist-cli/chunks/{maestro-ZRGFQ3MV.js → maestro-REMOLABE.js} +3 -3
  74. package/dist-cli/chunks/{maestro-generate-A5XZS5GC.js → maestro-generate-IU2RUQLO.js} +3 -3
  75. package/dist-cli/chunks/{mode-IFFZ55HM.js → mode-2GQRQPIW.js} +2 -2
  76. package/dist-cli/chunks/optional-demo-registry-FNHY44IB.js +2 -0
  77. package/dist-cli/chunks/{perf-44KZNTIV.js → perf-CU7CUMKX.js} +2 -2
  78. package/dist-cli/chunks/{record-GZLZNXYZ.js → record-XX3RELNP.js} +3 -3
  79. package/dist-cli/chunks/runtime-7TVHW27R.js +2 -0
  80. package/dist-cli/chunks/{screenshot-command-GL3STSWK.js → screenshot-command-UCB5GMXA.js} +3 -3
  81. package/dist-cli/chunks/{screenshots-capture-QSSBWHN6.js → screenshots-capture-3ALWS273.js} +2 -2
  82. package/dist-cli/chunks/{serve-AFK6X2Q3.js → serve-GDMRYWRG.js} +2 -2
  83. package/dist-cli/chunks/{setup-DYSDNEUE.js → setup-HPSMVFGT.js} +3 -3
  84. package/dist-cli/chunks/{skills-YXWQ43PZ.js → skills-B3FYCUCU.js} +2 -2
  85. package/dist-cli/chunks/{storage-C7IS5GTM.js → storage-42GBCFPY.js} +2 -2
  86. package/dist-cli/chunks/store-OTCZNVYJ.js +2 -0
  87. package/dist-cli/chunks/telemetry-LSW2JFI3.js +2 -0
  88. package/dist-cli/chunks/{timeline-FDTIHQ5V.js → timeline-VOVG5QCE.js} +2 -2
  89. package/dist-cli/chunks/{upgrade-VRQCFJEI.js → upgrade-AJJ3DDIH.js} +2 -2
  90. package/dist-cli/chunks/upload-D6KRF57A.js +2 -0
  91. package/dist-cli/chunks/{version-MP6NKJ27.js → version-I46ZOIB5.js} +2 -2
  92. package/dist-cli/chunks/{web-XYPFJHKW.js → web-TA7Z2M3K.js} +2 -2
  93. package/dist-cli/chunks/{what-happened-IM6UH24Q.js → what-happened-L7WYY5P3.js} +2 -2
  94. package/dist-lib/agent-daemon-client.cjs +1 -1
  95. package/dist-lib/agent-events.cjs +1 -1
  96. package/dist-lib/agent-identity.cjs +1 -1
  97. package/dist-lib/agent-sessions.cjs +1 -1
  98. package/dist-lib/attached-projects.cjs +1 -1
  99. package/dist-lib/auth/shared-session.cjs +1 -1
  100. package/dist-lib/backend-origin.cjs +1 -1
  101. package/dist-lib/beta.cjs +1 -1
  102. package/dist-lib/beta.mjs +1 -1
  103. package/dist-lib/bridge-constants.cjs +1 -1
  104. package/dist-lib/cli-constants.cjs +1 -1
  105. package/dist-lib/config.cjs +1 -1
  106. package/dist-lib/detox/index.cjs +1 -1
  107. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  108. package/dist-lib/home-paths.cjs +1 -1
  109. package/dist-lib/host/bridge-host.cjs +1 -1
  110. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  111. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  112. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  113. package/dist-lib/host/websocket-proxy.cjs +1 -1
  114. package/dist-lib/index.cjs +3 -2
  115. package/dist-lib/jump-to-source-babel.cjs +1 -1
  116. package/dist-lib/menu.cjs +1 -1
  117. package/dist-lib/menu.mjs +1 -1
  118. package/dist-lib/metro.cjs +3 -2
  119. package/dist-lib/profiles.cjs +1 -1
  120. package/dist-lib/render-mode.cjs +1 -1
  121. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  122. package/dist-lib/sdk.cjs +1 -1
  123. package/dist-lib/sdk.mjs +1 -1
  124. package/dist-lib/skills.cjs +12 -12
  125. package/dist-lib/vite.cjs +3 -2
  126. package/package.json +1 -1
  127. package/src/runtime-assets.ts +1 -0
  128. package/src/screenshots/frame-compose.ts +14 -12
  129. package/dist-cli/chunks/beta-NBANSL2S.js +0 -2
  130. package/dist-cli/chunks/chunk-PDFKRVDC.js +0 -2
  131. package/dist-cli/chunks/chunk-XTTXSDDA.js +0 -1
  132. package/dist-cli/chunks/chunk-ZZH2AFPJ.js +0 -1
  133. package/dist-cli/chunks/cli-version-BLKUTVJ2.js +0 -2
  134. package/dist-cli/chunks/daemon-FPKQPSSY.js +0 -2
  135. package/dist-cli/chunks/drivers-6P53DLMM.js +0 -2
  136. package/dist-cli/chunks/flow-53XFDYLL.js +0 -2
  137. package/dist-cli/chunks/help-MPYJLD7I.js +0 -2
  138. package/dist-cli/chunks/inspect-JBDDYUA5.js +0 -2
  139. package/dist-cli/chunks/install-desktop-BBP7AMK4.js +0 -2
  140. package/dist-cli/chunks/optional-demo-registry-TQZA65K3.js +0 -2
  141. package/dist-cli/chunks/runtime-F4FCEPPB.js +0 -2
  142. package/dist-cli/chunks/store-LVF2C2XZ.js +0 -2
  143. package/dist-cli/chunks/telemetry-5V3OXY6C.js +0 -2
  144. package/dist-cli/chunks/upload-CRCPDN6G.js +0 -2
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.270 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as y,b,c as R,d as r}from"./chunk-AG563BSO.js";import{d as w}from"./chunk-ERXCR7NU.js";import{G as d,H as u,I as $,l as p,z as g}from"./chunk-557IYHPC.js";import k from"fs";import{WebSocket as x}from"ws";async function H(t,e={}){let[s,...n]=t;if(!s||s==="--help"||s==="-h"){I();return}switch(s){case"install":return S(n,e);case"list":case"ls":return D(n);case"use":return N(n);case"remove":case"rm":return T(n);case"which":case"active":return L();case"pin":return _(n);case"unpin":return C();case"notes":case"changelog":return P(n);default:console.error(` unknown runtime subcommand: ${s}`),I(),process.exit(1)}}function I(){console.log(`
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as y,b,c as R,d as r}from"./chunk-WU3TJDWA.js";import{d as w}from"./chunk-UTYJQ65T.js";import{G as d,H as u,I as $,l as p,z as g}from"./chunk-QSUJV6FY.js";import k from"fs";import{WebSocket as x}from"ws";async function H(t,e={}){let[s,...n]=t;if(!s||s==="--help"||s==="-h"){I();return}switch(s){case"install":return S(n,e);case"list":case"ls":return D(n);case"use":return N(n);case"remove":case"rm":return T(n);case"which":case"active":return L();case"pin":return _(n);case"unpin":return C();case"notes":case"changelog":return P(n);default:console.error(` unknown runtime subcommand: ${s}`),I(),process.exit(1)}}function I(){console.log(`
3
3
  sootsim runtime \u2014 manage engine runtimes under ~/.sootsim/runtimes/
4
4
 
5
5
  usage:
@@ -26,4 +26,4 @@ examples:
26
26
  sootsim runtime install --channel beta
27
27
  sootsim runtime use 1.2.3
28
28
  sootsim runtime notes
29
- `)}async function S(t,e){let{version:s,flags:n}=U(t),o=n.channel??e.channel??"stable",c=n.force===!0,l=n.setActive!==!1;d(),console.log("sootsim runtime install"),console.log(` cdn: ${r.resolveCdnOrigin()}`);try{let i=await r.install({version:s,channel:o,force:c,setActive:l});console.log(` version: ${i.version} (channel: ${i.channel})`),i.installed?console.log(` installed ${i.version}`):console.log(` already installed at ${i.runtimeDir}`),l&&await m(i.version)}catch(i){console.error(` ${v(i)}`),process.exit(1)}}async function m(t){$(t),console.log(` active: ${t}`),await A(t)||console.log(` (no daemon running \u2014 next sootsim/electron launch will pick up ${t})`)}async function A(t){let{isDaemonLockfileFresh:e,readDaemonLockfile:s}=await import("./home-paths-CNNARPCT.js"),n=s();if(!e(n))return!1;let o=w();return new Promise(c=>{let l=!1,i=!1,f=O=>{l||(l=!0,c(O))},a=new x(`ws://127.0.0.1:${o}`,{handshakeTimeout:800}),h=setTimeout(()=>{try{a.close()}catch{}f(i)},1500);a.on("open",()=>{try{a.send(JSON.stringify({type:"runtime:use",version:t,id:0})),i=!0}catch{}setTimeout(()=>{try{a.close()}catch{}},100)}),a.on("close",()=>{clearTimeout(h),f(i)}),a.on("error",()=>{clearTimeout(h),f(!1)})})}async function D(t){d();let e=r.listInstalled(),s=u(),n=r.resolvePin();if(console.log("installed:"),e.length===0)console.log(" (none)");else for(let o of e)console.log(` ${o===s?"*":" "} ${o}${o===n?" (pinned)":""}`);n&&!e.includes(n)&&console.log(`pinned: ${n} (not installed \u2014 run \`sootsim runtime install\`)`);try{let o=await r.fetchManifest();console.log("available (latest per channel):");for(let[l,i]of Object.entries(o.channels))console.log(` ${l.padEnd(8)} ${i.latest}`);let c=Object.keys(o.versions).sort(y).reverse();if(c.length>1){console.log("hosted versions:");for(let l of c)console.log(` ${l}`)}}catch(o){console.log(`available: (could not fetch manifest: ${v(o)})`)}}async function N(t){let e=t[0];e||(console.error(" usage: sootsim runtime use <version>"),process.exit(1));let s=r.listInstalled();s.includes(e)||(console.error(` version ${e} is not installed`),console.error(` installed: ${s.join(", ")||"(none)"}`),console.error(` run \`sootsim runtime install ${e}\` first`),process.exit(1)),await m(e)}async function T(t){let e=t[0];e||(console.error(" usage: sootsim runtime remove <version>"),process.exit(1)),u()===e&&(console.error(` cannot remove active runtime ${e}`),console.error(" switch with `sootsim runtime use <other>` first, or install another version"),process.exit(1));let n=p(e);if(!k.existsSync(n)){console.error(` ${e} is not installed`);return}k.rmSync(n,{recursive:!0,force:!0}),console.log(` removed ${e}`)}async function L(){let t=u();if(!t){console.log(" no active runtime");return}console.log(t)}async function _(t){let e=t[0];if(!e){let n=r.resolvePin();n?console.log(` runtime pinned to ${n}`):(console.log(" no pin \u2014 runtime follows channel latest"),console.log(" usage: sootsim runtime pin <version>"));return}if(g({runtimeVersion:e}),console.log(` pinned runtime to ${e}`),r.listInstalled().includes(e)){u()!==e&&await m(e);return}try{let n=await r.install({version:e,setActive:!1});console.log(n.installed?` installed ${n.version}`:` already installed at ${n.runtimeDir}`),await m(e)}catch(n){console.error(` ${v(n)}`),console.error(` pin saved, but ${e} could not be installed \u2014 check \`sootsim runtime list\` for hosted versions`),process.exit(1)}}async function C(){let t=r.resolvePin();if(!t){console.log(" no pin set");return}g({runtimeVersion:void 0}),console.log(` unpinned (was ${t}) \u2014 runtime follows channel latest again`),console.log(" run `sootsim upgrade` to move to the latest now")}async function P(t){t.length>0&&(console.error(" usage: sootsim runtime notes"),process.exit(1));let e=u();e&&console.log(` active runtime: v${e}`),console.log(` release notes: ${R}`)}function U(t){let e={},s=[];for(let n=0;n<t.length;n++){let o=t[n];if(o==="--channel"&&n+1<t.length){e.channel=t[n+1],n++;continue}if(o.startsWith("--channel=")){e.channel=o.slice(10);continue}if(o==="--force"){e.force=!0;continue}if(o==="--set-active=false"||o==="--no-set-active"){e.setActive=!1;continue}s.push(o)}return{version:s[0]??null,flags:e}}function v(t){return t instanceof Error?t.message:String(t)}export{H as a};
29
+ `)}async function S(t,e){let{version:s,flags:n}=U(t),o=n.channel??e.channel??"stable",c=n.force===!0,l=n.setActive!==!1;d(),console.log("sootsim runtime install"),console.log(` cdn: ${r.resolveCdnOrigin()}`);try{let i=await r.install({version:s,channel:o,force:c,setActive:l});console.log(` version: ${i.version} (channel: ${i.channel})`),i.installed?console.log(` installed ${i.version}`):console.log(` already installed at ${i.runtimeDir}`),l&&await m(i.version)}catch(i){console.error(` ${v(i)}`),process.exit(1)}}async function m(t){$(t),console.log(` active: ${t}`),await A(t)||console.log(` (no daemon running \u2014 next sootsim/electron launch will pick up ${t})`)}async function A(t){let{isDaemonLockfileFresh:e,readDaemonLockfile:s}=await import("./home-paths-O6TNVGMZ.js"),n=s();if(!e(n))return!1;let o=w();return new Promise(c=>{let l=!1,i=!1,f=O=>{l||(l=!0,c(O))},a=new x(`ws://127.0.0.1:${o}`,{handshakeTimeout:800}),h=setTimeout(()=>{try{a.close()}catch{}f(i)},1500);a.on("open",()=>{try{a.send(JSON.stringify({type:"runtime:use",version:t,id:0})),i=!0}catch{}setTimeout(()=>{try{a.close()}catch{}},100)}),a.on("close",()=>{clearTimeout(h),f(i)}),a.on("error",()=>{clearTimeout(h),f(!1)})})}async function D(t){d();let e=r.listInstalled(),s=u(),n=r.resolvePin();if(console.log("installed:"),e.length===0)console.log(" (none)");else for(let o of e)console.log(` ${o===s?"*":" "} ${o}${o===n?" (pinned)":""}`);n&&!e.includes(n)&&console.log(`pinned: ${n} (not installed \u2014 run \`sootsim runtime install\`)`);try{let o=await r.fetchManifest();console.log("available (latest per channel):");for(let[l,i]of Object.entries(o.channels))console.log(` ${l.padEnd(8)} ${i.latest}`);let c=Object.keys(o.versions).sort(y).reverse();if(c.length>1){console.log("hosted versions:");for(let l of c)console.log(` ${l}`)}}catch(o){console.log(`available: (could not fetch manifest: ${v(o)})`)}}async function N(t){let e=t[0];e||(console.error(" usage: sootsim runtime use <version>"),process.exit(1));let s=r.listInstalled();s.includes(e)||(console.error(` version ${e} is not installed`),console.error(` installed: ${s.join(", ")||"(none)"}`),console.error(` run \`sootsim runtime install ${e}\` first`),process.exit(1)),await m(e)}async function T(t){let e=t[0];e||(console.error(" usage: sootsim runtime remove <version>"),process.exit(1)),u()===e&&(console.error(` cannot remove active runtime ${e}`),console.error(" switch with `sootsim runtime use <other>` first, or install another version"),process.exit(1));let n=p(e);if(!k.existsSync(n)){console.error(` ${e} is not installed`);return}k.rmSync(n,{recursive:!0,force:!0}),console.log(` removed ${e}`)}async function L(){let t=u();if(!t){console.log(" no active runtime");return}console.log(t)}async function _(t){let e=t[0];if(!e){let n=r.resolvePin();n?console.log(` runtime pinned to ${n}`):(console.log(" no pin \u2014 runtime follows channel latest"),console.log(" usage: sootsim runtime pin <version>"));return}if(g({runtimeVersion:e}),console.log(` pinned runtime to ${e}`),r.listInstalled().includes(e)){u()!==e&&await m(e);return}try{let n=await r.install({version:e,setActive:!1});console.log(n.installed?` installed ${n.version}`:` already installed at ${n.runtimeDir}`),await m(e)}catch(n){console.error(` ${v(n)}`),console.error(` pin saved, but ${e} could not be installed \u2014 check \`sootsim runtime list\` for hosted versions`),process.exit(1)}}async function C(){let t=r.resolvePin();if(!t){console.log(" no pin set");return}g({runtimeVersion:void 0}),console.log(` unpinned (was ${t}) \u2014 runtime follows channel latest again`),console.log(" run `sootsim upgrade` to move to the latest now")}async function P(t){t.length>0&&(console.error(" usage: sootsim runtime notes"),process.exit(1));let e=u();e&&console.log(` active runtime: v${e}`),console.log(` release notes: ${R}`)}function U(t){let e={},s=[];for(let n=0;n<t.length;n++){let o=t[n];if(o==="--channel"&&n+1<t.length){e.channel=t[n+1],n++;continue}if(o.startsWith("--channel=")){e.channel=o.slice(10);continue}if(o==="--force"){e.force=!0;continue}if(o==="--set-active=false"||o==="--no-set-active"){e.setActive=!1;continue}s.push(o)}return{version:s[0]??null,flags:e}}function v(t){return t instanceof Error?t.message:String(t)}export{H as a};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.270 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{c as h}from"./chunk-6JLIPPNB.js";import{b as A,e as k,g as L}from"./chunk-74HIBIJQ.js";import{K as w,L as S,M as I,N as B,g as F}from"./chunk-557IYHPC.js";import{WebSocket as T}from"ws";var W=null;function M(){let i=F();if(W?.homeDir===i)return W.world;let r=U();return W={homeDir:i,world:r},r}function U(){let i=S();if(i&&B(i))return{source:"dev-bridge",bridgePort:i.bridgePort,shellBaseUrl:i.shellPort?`http://localhost:${i.shellPort}/`:h};let r=w();return r&&I(r)?{source:"daemon",bridgePort:r.bridgePort,shellBaseUrl:r.runtimePort>0?`http://localhost:${r.runtimePort}/`:h}:{source:"default",bridgePort:7668,shellBaseUrl:h}}function _(i){let r=S();if(r&&B(r)&&r.bridgePort===i)return{source:"dev-bridge",shellBaseUrl:r.shellPort?`http://localhost:${r.shellPort}/`:h};let e=w();return e&&I(e)&&e.bridgePort===i?{source:"daemon",shellBaseUrl:e.runtimePort>0?`http://localhost:${e.runtimePort}/`:h}:null}function K(i){let r;try{let l=new URL(i);r=l.port?Number(l.port):l.protocol==="https:"?443:80}catch{return null}if(!Number.isFinite(r)||r<=0)return null;let e=S();if(e&&B(e)&&(e.shellPort===r||e.runtimePort===r||e.bridgePort===r))return e.bridgePort;let d=w();return d&&I(d)&&(d.runtimePort===r||d.bridgePort===r)?d.bridgePort:null}function D(){return M().bridgePort}function Q(i,r){let e=_(i),d=e?.source==="dev-bridge"?"dev bridge":e?.source==="daemon"?"daemon bridge":"bridge",l=e?`${e.source}.json`:"no lockfile",t=r??e?.shellBaseUrl;process.stderr.write(` \u2192 ${d} :${i} (${t?`shell ${t}, `:""}${l})
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{c as h}from"./chunk-MP55R5YC.js";import{b as A,e as k,g as L}from"./chunk-NXJIRSYB.js";import{K as w,L as S,M as I,N as B,g as F}from"./chunk-QSUJV6FY.js";import{WebSocket as T}from"ws";var W=null;function M(){let i=F();if(W?.homeDir===i)return W.world;let r=U();return W={homeDir:i,world:r},r}function U(){let i=S();if(i&&B(i))return{source:"dev-bridge",bridgePort:i.bridgePort,shellBaseUrl:i.shellPort?`http://localhost:${i.shellPort}/`:h};let r=w();return r&&I(r)?{source:"daemon",bridgePort:r.bridgePort,shellBaseUrl:r.runtimePort>0?`http://localhost:${r.runtimePort}/`:h}:{source:"default",bridgePort:7668,shellBaseUrl:h}}function _(i){let r=S();if(r&&B(r)&&r.bridgePort===i)return{source:"dev-bridge",shellBaseUrl:r.shellPort?`http://localhost:${r.shellPort}/`:h};let e=w();return e&&I(e)&&e.bridgePort===i?{source:"daemon",shellBaseUrl:e.runtimePort>0?`http://localhost:${e.runtimePort}/`:h}:null}function K(i){let r;try{let l=new URL(i);r=l.port?Number(l.port):l.protocol==="https:"?443:80}catch{return null}if(!Number.isFinite(r)||r<=0)return null;let e=S();if(e&&B(e)&&(e.shellPort===r||e.runtimePort===r||e.bridgePort===r))return e.bridgePort;let d=w();return d&&I(d)&&(d.runtimePort===r||d.bridgePort===r)?d.bridgePort:null}function D(){return M().bridgePort}function Q(i,r){let e=_(i),d=e?.source==="dev-bridge"?"dev bridge":e?.source==="daemon"?"daemon bridge":"bridge",l=e?`${e.source}.json`:"no lockfile",t=r??e?.shellBaseUrl;process.stderr.write(` \u2192 ${d} :${i} (${t?`shell ${t}, `:""}${l})
3
3
  `)}var $=class extends Error{lock;constructor(r,e){super(r),this.name="BridgeSimLockedError",this.lock=e}};function N(i){return i==="flag"?"via --sim":i==="saved"?"saved via `sootsim use`":"primary fallback \u2014 no sim pinned"}function z(i,r={}){let e=new Set,d=r.port??D(),l=r.commandTimeoutMs??15e3,t,u="none",P=new Set(r.stripBooleanFlags??[]),p=new Set(r.stripValueFlags??[]);for(let n=0;n<i.length;n++){let a=i[n];if(a==="--port"||a==="-p"){e.add(n),n+1<i.length&&(e.add(n+1),d=Number(i[n+1])),n++;continue}if(a.startsWith("--port=")){e.add(n),d=Number(a.slice(7));continue}if(a==="--timeout"){e.add(n),n+1<i.length&&(e.add(n+1),l=Number(i[n+1])),n++;continue}if(a==="--sim"||a==="--session"||a==="--tab"){e.add(n),n+1<i.length&&(e.add(n+1),t=i[n+1]?.trim()||void 0,u="flag"),n++;continue}let s=a.startsWith("--sim=")?a.slice(6):a.startsWith("--session=")?a.slice(10):a.startsWith("--tab=")?a.slice(6):void 0;if(s!==void 0){e.add(n),t=s.trim()||void 0,u="flag";continue}if(P.has(a)){e.add(n);continue}p.has(a)&&(e.add(n),n+1<i.length&&e.add(n+1),n++)}if(!t){let n=k();n&&(t=n.trim()||void 0,u="saved")}return{positional:i.filter((n,a)=>!e.has(a)),wsPort:d,simId:t,simIdSource:u,commandTimeoutMs:l}}function R(i,r={}){let e=1,d=r.commandTimeoutMs??15e3,l=new Map,t=new T(`ws://localhost:${i}`),u=A(),P=new Promise((s,o)=>{t.on("open",()=>{try{t.send(JSON.stringify({type:"bridge:hello",id:0,cliIdentityKey:u.key,cliIdentitySource:u.source,cliLabel:r.cliLabel}))}catch{}s()}),t.on("error",c=>{let m=c.message?`: ${c.message}`:"";o(new Error(`could not connect to ws://localhost:${i}${m}`))})}),p=!1,n=!1;function a(s,o){if(n||process.env.SOOTSIM_QUIET_TARGET_NOTICE==="1"||s.startsWith("bridge:")||s==="focus"||s==="close")return;n=!0;let c=o??"primary",m=N(o?r.simIdSource:"none");process.stderr.write(` \u2192 ${c} (${m})
4
4
  `)}return t.on("message",s=>{let o;try{o=JSON.parse(s.toString())}catch{return}if(o.id===0)return;let c=l.get(o.id);c&&(l.delete(o.id),o._otherCliCount>0&&!p&&(p=!0,process.stderr.write(`
5
5
  \u26A0 ${o._otherCliCount} other CLI identity/identities are driving this sim
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.270 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{e as p}from"./chunk-HWGKGIWE.js";import{a as c,b as l}from"./chunk-ABSUFSOH.js";import{a}from"./chunk-3VIMSXQZ.js";async function g(e,t){if(t)return t.replace(/\/$/,"");if(e.kind==="session"&&e.origin)return e.origin.replace(/\/$/,"");let i=a();return i?.origin?i.origin.replace(/\/$/,""):(await p()).replace(/\/$/,"")}async function m(e,t={}){let i=c();if(i||(process.stderr.write(`
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{e as p}from"./chunk-MVXVG2BX.js";import{a as c,b as l}from"./chunk-5PLAZK5V.js";import{a}from"./chunk-RBRFATPJ.js";async function g(e,t){if(t)return t.replace(/\/$/,"");if(e.kind==="session"&&e.origin)return e.origin.replace(/\/$/,"");let i=a();return i?.origin?i.origin.replace(/\/$/,""):(await p()).replace(/\/$/,"")}async function m(e,t={}){let i=c();if(i||(process.stderr.write(`
3
3
  sootsim ${e} needs auth before it can check recording access.
4
4
 
5
5
  pick one:
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.270 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as R,b as U}from"./chunk-TLNGREAA.js";import{c as F}from"./chunk-ZTKDHPA6.js";import{g as N,j as E,r as _,s as v,t as B}from"./chunk-557IYHPC.js";import{a as O}from"./chunk-4HPWZVBS.js";import{execFileSync as W,spawnSync as s}from"child_process";import{existsSync as a,mkdirSync as x,readFileSync as nt,realpathSync as ot,rmSync as $,writeFileSync as H}from"fs";import{homedir as P}from"os";import{basename as st,dirname as T,resolve as f,sep as Y}from"path";import{execFileSync as X}from"child_process";import{chmodSync as Q,mkdirSync as I,rmSync as z,writeFileSync as A}from"fs";import{dirname as L}from"path";var J="dev.sootsim.daemon",j="SootSim Daemon",M="0.1.36";function V(t,e,r){let n=v(),o=B(),c=L(L(o)),l=L(o),u=`${c}/Resources`;z(n,{recursive:!0,force:!0}),I(_(),{recursive:!0}),I(l,{recursive:!0}),I(u,{recursive:!0}),A(`${c}/Info.plist`,Z()),A(`${c}/PkgInfo`,"APPL????"),A(o,tt(t,e,r)),Q(o,493);try{X("codesign",["--force","--sign","-","--deep",n],{stdio:"pipe"})}catch(i){let p=i instanceof Error?i.message:String(i);console.warn(` warning: ad-hoc codesign of ${n} failed: ${p}
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as R,b as U}from"./chunk-Z6WIJUFD.js";import{c as F}from"./chunk-4ISBAFYP.js";import{g as N,j as E,r as _,s as v,t as B}from"./chunk-QSUJV6FY.js";import{a as O}from"./chunk-7MWXZLC3.js";import{execFileSync as W,spawnSync as s}from"child_process";import{existsSync as a,mkdirSync as x,readFileSync as nt,realpathSync as ot,rmSync as $,writeFileSync as H}from"fs";import{homedir as P}from"os";import{basename as st,dirname as T,resolve as f,sep as Y}from"path";import{execFileSync as X}from"child_process";import{chmodSync as Q,mkdirSync as I,rmSync as z,writeFileSync as A}from"fs";import{dirname as L}from"path";var J="dev.sootsim.daemon",j="SootSim Daemon",M="0.1.36";function V(t,e,r){let n=v(),o=B(),c=L(L(o)),l=L(o),u=`${c}/Resources`;z(n,{recursive:!0,force:!0}),I(_(),{recursive:!0}),I(l,{recursive:!0}),I(u,{recursive:!0}),A(`${c}/Info.plist`,Z()),A(`${c}/PkgInfo`,"APPL????"),A(o,tt(t,e,r)),Q(o,493);try{X("codesign",["--force","--sign","-","--deep",n],{stdio:"pipe"})}catch(i){let p=i instanceof Error?i.message:String(i);console.warn(` warning: ad-hoc codesign of ${n} failed: ${p}
3
3
  the daemon will still run, but Login Items may show a generic name.`)}return{bundlePath:n,launcherPath:o}}function Z(){return`<?xml version="1.0" encoding="UTF-8"?>
4
4
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
5
5
  <plist version="1.0">
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.270 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{b as ms}from"./chunk-5IHDZOMR.js";var hs={};ms(hs,{Alias:()=>ee,CST:()=>cs,Composer:()=>be,Document:()=>se,Lexer:()=>Be,LineCounter:()=>De,Pair:()=>v,Parser:()=>we,Scalar:()=>y,Schema:()=>ve,YAMLError:()=>_e,YAMLMap:()=>$,YAMLParseError:()=>R,YAMLSeq:()=>B,YAMLWarning:()=>Pe,isAlias:()=>F,isCollection:()=>L,isDocument:()=>x,isMap:()=>U,isNode:()=>I,isPair:()=>T,isScalar:()=>E,isSeq:()=>V,parse:()=>un,parseAllDocuments:()=>fn,parseDocument:()=>us,stringify:()=>hn,visit:()=>Q,visitAsync:()=>je});var tt=Symbol.for("yaml.alias"),st=Symbol.for("yaml.document"),Y=Symbol.for("yaml.map"),qt=Symbol.for("yaml.pair"),q=Symbol.for("yaml.scalar"),re=Symbol.for("yaml.seq"),K=Symbol.for("yaml.node.type"),F=s=>!!s&&typeof s=="object"&&s[K]===tt,x=s=>!!s&&typeof s=="object"&&s[K]===st,U=s=>!!s&&typeof s=="object"&&s[K]===Y,T=s=>!!s&&typeof s=="object"&&s[K]===qt,E=s=>!!s&&typeof s=="object"&&s[K]===q,V=s=>!!s&&typeof s=="object"&&s[K]===re;function L(s){if(s&&typeof s=="object")switch(s[K]){case Y:case re:return!0}return!1}function I(s){if(s&&typeof s=="object")switch(s[K]){case tt:case Y:case q:case re:return!0}return!1}var nt=s=>(E(s)||L(s))&&!!s.anchor;var j=Symbol("break visit"),ds=Symbol("skip children"),z=Symbol("remove node");function Q(s,e){let t=gs(e);x(s)?ke(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):ke(null,s,t,Object.freeze([]))}Q.BREAK=j;Q.SKIP=ds;Q.REMOVE=z;function ke(s,e,t,n){let i=ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),ke(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=ke(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=ke("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=ke("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}async function je(s,e){let t=gs(e);x(s)?await Ne(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):await Ne(null,s,t,Object.freeze([]))}je.BREAK=j;je.SKIP=ds;je.REMOVE=z;async function Ne(s,e,t,n){let i=await ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),Ne(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=await Ne(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=await Ne("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=await Ne("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}function gs(s){return typeof s=="object"&&(s.Collection||s.Node||s.Value)?Object.assign({Alias:s.Node,Map:s.Node,Scalar:s.Node,Seq:s.Node},s.Value&&{Map:s.Value,Scalar:s.Value,Seq:s.Value},s.Collection&&{Map:s.Collection,Seq:s.Collection},s):s}function ys(s,e,t,n){if(typeof t=="function")return t(s,e,n);if(U(e))return t.Map?.(s,e,n);if(V(e))return t.Seq?.(s,e,n);if(T(e))return t.Pair?.(s,e,n);if(E(e))return t.Scalar?.(s,e,n);if(F(e))return t.Alias?.(s,e,n)}function bs(s,e,t){let n=e[e.length-1];if(L(n))n.items[s]=t;else if(T(n))s==="key"?n.key=t:n.value=t;else if(x(n))n.contents=t;else{let i=F(n)?"alias":"scalar";throw new Error(`Cannot replace node with ${i} parent`)}}var pn={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},mn=s=>s.replace(/[!,[\]{}]/g,e=>pn[e]),Z=class s{constructor(e,t){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},s.defaultYaml,e),this.tags=Object.assign({},s.defaultTags,t)}clone(){let e=new s(this.yaml,this.tags);return e.docStart=this.docStart,e}atDocument(){let e=new s(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:s.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},s.defaultTags);break}return e}add(e,t){this.atNextDocument&&(this.yaml={explicit:s.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},s.defaultTags),this.atNextDocument=!1);let n=e.trim().split(/[ \t]+/),i=n.shift();switch(i){case"%TAG":{if(n.length!==2&&(t(0,"%TAG directive should contain exactly two parts"),n.length<2))return!1;let[r,o]=n;return this.tags[r]=o,!0}case"%YAML":{if(this.yaml.explicit=!0,n.length!==1)return t(0,"%YAML directive should contain exactly one part"),!1;let[r]=n;if(r==="1.1"||r==="1.2")return this.yaml.version=r,!0;{let o=/^\d+\.\d+$/.test(r);return t(6,`Unsupported YAML version ${r}`,o),!1}}default:return t(0,`Unknown directive ${i}`,!0),!1}}tagName(e,t){if(e==="!")return"!";if(e[0]!=="!")return t(`Not a valid tag: ${e}`),null;if(e[1]==="<"){let o=e.slice(2,-1);return o==="!"||o==="!!"?(t(`Verbatim tags aren't resolved, so ${e} is invalid.`),null):(e[e.length-1]!==">"&&t("Verbatim tags must end with a >"),o)}let[,n,i]=e.match(/^(.*!)([^!]*)$/s);i||t(`The ${e} tag has no suffix`);let r=this.tags[n];if(r)try{return r+decodeURIComponent(i)}catch(o){return t(String(o)),null}return n==="!"?e:(t(`Could not resolve tag: ${e}`),null)}tagString(e){for(let[t,n]of Object.entries(this.tags))if(e.startsWith(n))return t+mn(e.substring(n.length));return e[0]==="!"?e:`!<${e}>`}toString(e){let t=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],n=Object.entries(this.tags),i;if(e&&n.length>0&&I(e.contents)){let r={};Q(e.contents,(o,l)=>{I(l)&&l.tag&&(r[l.tag]=!0)}),i=Object.keys(r)}else i=[];for(let[r,o]of n)r==="!!"&&o==="tag:yaml.org,2002:"||(!e||i.some(l=>l.startsWith(o)))&&t.push(`%TAG ${r} ${o}`);return t.join(`
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{b as ms}from"./chunk-KDQDKEGD.js";var hs={};ms(hs,{Alias:()=>ee,CST:()=>cs,Composer:()=>be,Document:()=>se,Lexer:()=>Be,LineCounter:()=>De,Pair:()=>v,Parser:()=>we,Scalar:()=>y,Schema:()=>ve,YAMLError:()=>_e,YAMLMap:()=>$,YAMLParseError:()=>R,YAMLSeq:()=>B,YAMLWarning:()=>Pe,isAlias:()=>F,isCollection:()=>L,isDocument:()=>x,isMap:()=>U,isNode:()=>I,isPair:()=>T,isScalar:()=>E,isSeq:()=>V,parse:()=>un,parseAllDocuments:()=>fn,parseDocument:()=>us,stringify:()=>hn,visit:()=>Q,visitAsync:()=>je});var tt=Symbol.for("yaml.alias"),st=Symbol.for("yaml.document"),Y=Symbol.for("yaml.map"),qt=Symbol.for("yaml.pair"),q=Symbol.for("yaml.scalar"),re=Symbol.for("yaml.seq"),K=Symbol.for("yaml.node.type"),F=s=>!!s&&typeof s=="object"&&s[K]===tt,x=s=>!!s&&typeof s=="object"&&s[K]===st,U=s=>!!s&&typeof s=="object"&&s[K]===Y,T=s=>!!s&&typeof s=="object"&&s[K]===qt,E=s=>!!s&&typeof s=="object"&&s[K]===q,V=s=>!!s&&typeof s=="object"&&s[K]===re;function L(s){if(s&&typeof s=="object")switch(s[K]){case Y:case re:return!0}return!1}function I(s){if(s&&typeof s=="object")switch(s[K]){case tt:case Y:case q:case re:return!0}return!1}var nt=s=>(E(s)||L(s))&&!!s.anchor;var j=Symbol("break visit"),ds=Symbol("skip children"),z=Symbol("remove node");function Q(s,e){let t=gs(e);x(s)?ke(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):ke(null,s,t,Object.freeze([]))}Q.BREAK=j;Q.SKIP=ds;Q.REMOVE=z;function ke(s,e,t,n){let i=ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),ke(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=ke(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=ke("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=ke("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}async function je(s,e){let t=gs(e);x(s)?await Ne(null,s.contents,t,Object.freeze([s]))===z&&(s.contents=null):await Ne(null,s,t,Object.freeze([]))}je.BREAK=j;je.SKIP=ds;je.REMOVE=z;async function Ne(s,e,t,n){let i=await ys(s,e,t,n);if(I(i)||T(i))return bs(s,n,i),Ne(s,i,t,n);if(typeof i!="symbol"){if(L(e)){n=Object.freeze(n.concat(e));for(let r=0;r<e.items.length;++r){let o=await Ne(r,e.items[r],t,n);if(typeof o=="number")r=o-1;else{if(o===j)return j;o===z&&(e.items.splice(r,1),r-=1)}}}else if(T(e)){n=Object.freeze(n.concat(e));let r=await Ne("key",e.key,t,n);if(r===j)return j;r===z&&(e.key=null);let o=await Ne("value",e.value,t,n);if(o===j)return j;o===z&&(e.value=null)}}return i}function gs(s){return typeof s=="object"&&(s.Collection||s.Node||s.Value)?Object.assign({Alias:s.Node,Map:s.Node,Scalar:s.Node,Seq:s.Node},s.Value&&{Map:s.Value,Scalar:s.Value,Seq:s.Value},s.Collection&&{Map:s.Collection,Seq:s.Collection},s):s}function ys(s,e,t,n){if(typeof t=="function")return t(s,e,n);if(U(e))return t.Map?.(s,e,n);if(V(e))return t.Seq?.(s,e,n);if(T(e))return t.Pair?.(s,e,n);if(E(e))return t.Scalar?.(s,e,n);if(F(e))return t.Alias?.(s,e,n)}function bs(s,e,t){let n=e[e.length-1];if(L(n))n.items[s]=t;else if(T(n))s==="key"?n.key=t:n.value=t;else if(x(n))n.contents=t;else{let i=F(n)?"alias":"scalar";throw new Error(`Cannot replace node with ${i} parent`)}}var pn={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},mn=s=>s.replace(/[!,[\]{}]/g,e=>pn[e]),Z=class s{constructor(e,t){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},s.defaultYaml,e),this.tags=Object.assign({},s.defaultTags,t)}clone(){let e=new s(this.yaml,this.tags);return e.docStart=this.docStart,e}atDocument(){let e=new s(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:s.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},s.defaultTags);break}return e}add(e,t){this.atNextDocument&&(this.yaml={explicit:s.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},s.defaultTags),this.atNextDocument=!1);let n=e.trim().split(/[ \t]+/),i=n.shift();switch(i){case"%TAG":{if(n.length!==2&&(t(0,"%TAG directive should contain exactly two parts"),n.length<2))return!1;let[r,o]=n;return this.tags[r]=o,!0}case"%YAML":{if(this.yaml.explicit=!0,n.length!==1)return t(0,"%YAML directive should contain exactly one part"),!1;let[r]=n;if(r==="1.1"||r==="1.2")return this.yaml.version=r,!0;{let o=/^\d+\.\d+$/.test(r);return t(6,`Unsupported YAML version ${r}`,o),!1}}default:return t(0,`Unknown directive ${i}`,!0),!1}}tagName(e,t){if(e==="!")return"!";if(e[0]!=="!")return t(`Not a valid tag: ${e}`),null;if(e[1]==="<"){let o=e.slice(2,-1);return o==="!"||o==="!!"?(t(`Verbatim tags aren't resolved, so ${e} is invalid.`),null):(e[e.length-1]!==">"&&t("Verbatim tags must end with a >"),o)}let[,n,i]=e.match(/^(.*!)([^!]*)$/s);i||t(`The ${e} tag has no suffix`);let r=this.tags[n];if(r)try{return r+decodeURIComponent(i)}catch(o){return t(String(o)),null}return n==="!"?e:(t(`Could not resolve tag: ${e}`),null)}tagString(e){for(let[t,n]of Object.entries(this.tags))if(e.startsWith(n))return t+mn(e.substring(n.length));return e[0]==="!"?e:`!<${e}>`}toString(e){let t=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],n=Object.entries(this.tags),i;if(e&&n.length>0&&I(e.contents)){let r={};Q(e.contents,(o,l)=>{I(l)&&l.tag&&(r[l.tag]=!0)}),i=Object.keys(r)}else i=[];for(let[r,o]of n)r==="!!"&&o==="tag:yaml.org,2002:"||(!e||i.some(l=>l.startsWith(o)))&&t.push(`%TAG ${r} ${o}`);return t.join(`
3
3
  `)}};Z.defaultYaml={explicit:!1,version:"1.2"};Z.defaultTags={"!!":"tag:yaml.org,2002:"};function it(s){if(/[\x00-\x19\s,[\]{}]/.test(s)){let t=`Anchor must not contain whitespace or control characters: ${JSON.stringify(s)}`;throw new Error(t)}return!0}function Rt(s){let e=new Set;return Q(s,{Value(t,n){n.anchor&&e.add(n.anchor)}}),e}function Ft(s,e){for(let t=1;;++t){let n=`${s}${t}`;if(!e.has(n))return n}}function ws(s,e){let t=[],n=new Map,i=null;return{onAnchor:r=>{t.push(r),i??(i=Rt(s));let o=Ft(e,i);return i.add(o),o},setAnchors:()=>{for(let r of t){let o=n.get(r);if(typeof o=="object"&&o.anchor&&(E(o.node)||L(o.node)))o.node.anchor=o.anchor;else{let l=new Error("Failed to resolve repeated object (this should not happen)");throw l.source=r,l}}},sourceObjects:n}}function fe(s,e,t,n){if(n&&typeof n=="object")if(Array.isArray(n))for(let i=0,r=n.length;i<r;++i){let o=n[i],l=fe(s,n,String(i),o);l===void 0?delete n[i]:l!==o&&(n[i]=l)}else if(n instanceof Map)for(let i of Array.from(n.keys())){let r=n.get(i),o=fe(s,n,i,r);o===void 0?n.delete(i):o!==r&&n.set(i,o)}else if(n instanceof Set)for(let i of Array.from(n)){let r=fe(s,n,i,i);r===void 0?n.delete(i):r!==i&&(n.delete(i),n.add(r))}else for(let[i,r]of Object.entries(n)){let o=fe(s,n,i,r);o===void 0?delete n[i]:o!==r&&(n[i]=o)}return s.call(e,t,n)}function M(s,e,t){if(Array.isArray(s))return s.map((n,i)=>M(n,String(i),t));if(s&&typeof s.toJSON=="function"){if(!t||!nt(s))return s.toJSON(e,t);let n={aliasCount:0,count:1,res:void 0};t.anchors.set(s,n),t.onCreate=r=>{n.res=r,delete t.onCreate};let i=s.toJSON(e,t);return t.onCreate&&t.onCreate(i),i}return typeof s=="bigint"&&!t?.keep?Number(s):s}var ue=class{constructor(e){Object.defineProperty(this,K,{value:e})}clone(){let e=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return this.range&&(e.range=this.range.slice()),e}toJS(e,{mapAsMap:t,maxAliasCount:n,onAnchor:i,reviver:r}={}){if(!x(e))throw new TypeError("A document argument is required");let o={anchors:new Map,doc:e,keep:!0,mapAsMap:t===!0,mapKeyWarned:!1,maxAliasCount:typeof n=="number"?n:100},l=M(this,"",o);if(typeof i=="function")for(let{count:a,res:c}of o.anchors.values())i(c,a);return typeof r=="function"?fe(r,{"":l},"",l):l}};var ee=class extends ue{constructor(e){super(tt),this.source=e,Object.defineProperty(this,"tag",{set(){throw new Error("Alias nodes cannot have tags")}})}resolve(e,t){if(t?.maxAliasCount===0)throw new ReferenceError("Alias resolution is disabled");let n;t?.aliasResolveCache?n=t.aliasResolveCache:(n=[],Q(e,{Node:(r,o)=>{(F(o)||nt(o))&&n.push(o)}}),t&&(t.aliasResolveCache=n));let i;for(let r of n){if(r===this)break;r.anchor===this.source&&(i=r)}return i}toJSON(e,t){if(!t)return{source:this.source};let{anchors:n,doc:i,maxAliasCount:r}=t,o=this.resolve(i,t);if(!o){let a=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new ReferenceError(a)}let l=n.get(o);if(l||(M(o,null,t),l=n.get(o)),l?.res===void 0){let a="This should not happen: Alias anchor was not resolved?";throw new ReferenceError(a)}if(r>=0&&(l.count+=1,l.aliasCount===0&&(l.aliasCount=rt(i,o,n)),l.count*l.aliasCount>r)){let a="Excessive alias count indicates a resource exhaustion attack";throw new ReferenceError(a)}return l.res}toString(e,t,n){let i=`*${this.source}`;if(e){if(it(this.source),e.options.verifyAliasOrder&&!e.anchors.has(this.source)){let r=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new Error(r)}if(e.implicitKey)return`${i} `}return i}};function rt(s,e,t){if(F(e)){let n=e.resolve(s),i=t&&n&&t.get(n);return i?i.count*i.aliasCount:0}else if(L(e)){let n=0;for(let i of e.items){let r=rt(s,i,t);r>n&&(n=r)}return n}else if(T(e)){let n=rt(s,e.key,t),i=rt(s,e.value,t);return Math.max(n,i)}return 1}var ot=s=>!s||typeof s!="function"&&typeof s!="object",y=class extends ue{constructor(e){super(q),this.value=e}toJSON(e,t){return t?.keep?this.value:M(this.value,e,t)}toString(){return String(this.value)}};y.BLOCK_FOLDED="BLOCK_FOLDED";y.BLOCK_LITERAL="BLOCK_LITERAL";y.PLAIN="PLAIN";y.QUOTE_DOUBLE="QUOTE_DOUBLE";y.QUOTE_SINGLE="QUOTE_SINGLE";var dn="tag:yaml.org,2002:";function gn(s,e,t){if(e){let n=t.filter(r=>r.tag===e),i=n.find(r=>!r.format)??n[0];if(!i)throw new Error(`Tag ${e} not found`);return i}return t.find(n=>n.identify?.(s)&&!n.format)}function oe(s,e,t){if(x(s)&&(s=s.contents),I(s))return s;if(T(s)){let f=t.schema[Y].createNode?.(t.schema,null,t);return f.items.push(s),f}(s instanceof String||s instanceof Number||s instanceof Boolean||typeof BigInt<"u"&&s instanceof BigInt)&&(s=s.valueOf());let{aliasDuplicateObjects:n,onAnchor:i,onTagObj:r,schema:o,sourceObjects:l}=t,a;if(n&&s&&typeof s=="object"){if(a=l.get(s),a)return a.anchor??(a.anchor=i(s)),new ee(a.anchor);a={anchor:null,node:null},l.set(s,a)}e?.startsWith("!!")&&(e=dn+e.slice(2));let c=gn(s,e,o.tags);if(!c){if(s&&typeof s.toJSON=="function"&&(s=s.toJSON()),!s||typeof s!="object"){let f=new y(s);return a&&(a.node=f),f}c=s instanceof Map?o[Y]:Symbol.iterator in Object(s)?o[re]:o[Y]}r&&(r(c),delete t.onTagObj);let p=c?.createNode?c.createNode(t.schema,s,t):typeof c?.nodeClass?.from=="function"?c.nodeClass.from(t.schema,s,t):new y(s);return e?p.tag=e:c.default||(p.tag=c.tag),a&&(a.node=p),p}function qe(s,e,t){let n=t;for(let i=e.length-1;i>=0;--i){let r=e[i];if(typeof r=="number"&&Number.isInteger(r)&&r>=0){let o=[];o[r]=n,n=o}else n=new Map([[r,n]])}return oe(n,void 0,{aliasDuplicateObjects:!1,keepUndefined:!1,onAnchor:()=>{throw new Error("This should not happen, please report a bug.")},schema:s,sourceObjects:new Map})}var Ae=s=>s==null||typeof s=="object"&&!!s[Symbol.iterator]().next().done,Oe=class extends ue{constructor(e,t){super(e),Object.defineProperty(this,"schema",{value:t,configurable:!0,enumerable:!1,writable:!0})}clone(e){let t=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return e&&(t.schema=e),t.items=t.items.map(n=>I(n)||T(n)?n.clone(e):n),this.range&&(t.range=this.range.slice()),t}addIn(e,t){if(Ae(e))this.add(t);else{let[n,...i]=e,r=this.get(n,!0);if(L(r))r.addIn(i,t);else if(r===void 0&&this.schema)this.set(n,qe(this.schema,i,t));else throw new Error(`Expected YAML collection at ${n}. Remaining path: ${i}`)}}deleteIn(e){let[t,...n]=e;if(n.length===0)return this.delete(t);let i=this.get(t,!0);if(L(i))return i.deleteIn(n);throw new Error(`Expected YAML collection at ${t}. Remaining path: ${n}`)}getIn(e,t){let[n,...i]=e,r=this.get(n,!0);return i.length===0?!t&&E(r)?r.value:r:L(r)?r.getIn(i,t):void 0}hasAllNullValues(e){return this.items.every(t=>{if(!T(t))return!1;let n=t.value;return n==null||e&&E(n)&&n.value==null&&!n.commentBefore&&!n.comment&&!n.tag})}hasIn(e){let[t,...n]=e;if(n.length===0)return this.has(t);let i=this.get(t,!0);return L(i)?i.hasIn(n):!1}setIn(e,t){let[n,...i]=e;if(i.length===0)this.set(n,t);else{let r=this.get(n,!0);if(L(r))r.setIn(i,t);else if(r===void 0&&this.schema)this.set(n,qe(this.schema,i,t));else throw new Error(`Expected YAML collection at ${n}. Remaining path: ${i}`)}}};var Ss=s=>s.replace(/^(?!$)(?: $)?/gm,"#");function J(s,e){return/^\n+$/.test(s)?s.substring(1):e?s.replace(/^(?! *$)/gm,e):s}var te=(s,e,t)=>s.endsWith(`
4
4
  `)?J(t,e):t.includes(`
5
5
  `)?`
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.270 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as C,b as D}from"./chunk-FNBFRG64.js";import{H as E}from"./chunk-557IYHPC.js";var N="sootsimConfig";function p(e){return!!e&&Object.keys(e).length>0}function $(e){return e?p(e.modules)||p(e.turboModules)||p(e.nativeModules)||p(e.env)||p(e.network?.remap)||p(e.settings)||p(e.initialState):!1}function A(e,n){let t=new URL(e);return $(n)?t.searchParams.set(N,JSON.stringify(n)):t.searchParams.delete(N),t.toString()}var pe="/index.bundle?platform=ios&dev=true&hot=true&minify=false";function j(e){return/^https?:\/\//i.test(e)}function O(e){return e.endsWith(".bundle")}function H(e){process.env.SOOTSIM_PREVIEW_PROD_BUNDLE&&(e.searchParams.set("dev","false"),e.searchParams.set("minify","true"),e.searchParams.has("hot")&&e.searchParams.set("hot","false"))}function I(e){try{let n=j(e),t=new URL(e,"http://sootsim.local");return t.pathname=t.pathname.replace(/\.\.bundle$/,".bundle"),O(t.pathname)?(t.searchParams.delete("transform.bytecode"),t.searchParams.get("lazy")==="true"&&t.searchParams.set("lazy","false"),H(t),n?t.toString():`${t.pathname}${t.search}${t.hash}`):e}catch{return e}}function ge(e,n){try{let t=j(e),o=new URL(e,"http://sootsim.local");return O(o.pathname)?(o.searchParams.set("hot",n?"true":"false"),t?o.toString():`${o.pathname}${o.search}${o.hash}`):e}catch{return e}}import{exec as B}from"child_process";import W from"http";import F from"net";import{promisify as G}from"util";var T=G(B);C();var z=250,J=1500,K=120;function V(e,n=K){return new Promise(t=>{let o=new F.Socket,s=!1,i=a=>{s||(s=!0,o.destroy(),t(a))};o.setTimeout(n),o.once("connect",()=>i(!0)),o.once("timeout",()=>i(!1)),o.once("error",()=>i(!1)),o.connect(e,"localhost")})}function h(e,n,t="GET",o=z,s={}){return new Promise(i=>{let a=W.request({hostname:"localhost",port:e,path:n,method:t,timeout:o,headers:s},r=>{let c="";r.on("data",l=>c+=l.toString());let u=(()=>{let l=r.headers["content-type"];if(typeof l=="string")return l;if(Array.isArray(l))return l[0]})();r.on("end",()=>i({statusCode:r.statusCode||0,body:c,contentType:u}))});a.on("error",()=>i(null)),a.setTimeout(o,()=>{a.destroy(),i(null)}),a.end()})}var q=[8081,8082,8083,8084,8085,8086,3e3,3001,19e3].map(e=>({port:e,pid:0}));function k(e,n){return!(e<=0||e>=2e4||n.has(e)||e>=5170&&e<=5200)}async function Y(e=[]){let n=new Set(e);try{let{stdout:t}=await T("lsof -iTCP -sTCP:LISTEN -P -n 2>/dev/null | grep -E '^(node|bun)'",{encoding:"utf8",timeout:2e3});if(t.trim()){let o=new Map;for(let s of t.trim().split(`
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as C,b as D}from"./chunk-KNBKEQMZ.js";import{H as E}from"./chunk-QSUJV6FY.js";var N="sootsimConfig";function p(e){return!!e&&Object.keys(e).length>0}function $(e){return e?p(e.modules)||p(e.turboModules)||p(e.nativeModules)||p(e.env)||p(e.network?.remap)||p(e.settings)||p(e.initialState):!1}function A(e,n){let t=new URL(e);return $(n)?t.searchParams.set(N,JSON.stringify(n)):t.searchParams.delete(N),t.toString()}var pe="/index.bundle?platform=ios&dev=true&hot=true&minify=false";function j(e){return/^https?:\/\//i.test(e)}function O(e){return e.endsWith(".bundle")}function H(e){process.env.SOOTSIM_PREVIEW_PROD_BUNDLE&&(e.searchParams.set("dev","false"),e.searchParams.set("minify","true"),e.searchParams.has("hot")&&e.searchParams.set("hot","false"))}function I(e){try{let n=j(e),t=new URL(e,"http://sootsim.local");return t.pathname=t.pathname.replace(/\.\.bundle$/,".bundle"),O(t.pathname)?(t.searchParams.delete("transform.bytecode"),t.searchParams.get("lazy")==="true"&&t.searchParams.set("lazy","false"),H(t),n?t.toString():`${t.pathname}${t.search}${t.hash}`):e}catch{return e}}function ge(e,n){try{let t=j(e),o=new URL(e,"http://sootsim.local");return O(o.pathname)?(o.searchParams.set("hot",n?"true":"false"),t?o.toString():`${o.pathname}${o.search}${o.hash}`):e}catch{return e}}import{exec as B}from"child_process";import W from"http";import F from"net";import{promisify as G}from"util";var T=G(B);C();var z=250,J=1500,K=120;function V(e,n=K){return new Promise(t=>{let o=new F.Socket,s=!1,i=a=>{s||(s=!0,o.destroy(),t(a))};o.setTimeout(n),o.once("connect",()=>i(!0)),o.once("timeout",()=>i(!1)),o.once("error",()=>i(!1)),o.connect(e,"localhost")})}function h(e,n,t="GET",o=z,s={}){return new Promise(i=>{let a=W.request({hostname:"localhost",port:e,path:n,method:t,timeout:o,headers:s},r=>{let c="";r.on("data",l=>c+=l.toString());let u=(()=>{let l=r.headers["content-type"];if(typeof l=="string")return l;if(Array.isArray(l))return l[0]})();r.on("end",()=>i({statusCode:r.statusCode||0,body:c,contentType:u}))});a.on("error",()=>i(null)),a.setTimeout(o,()=>{a.destroy(),i(null)}),a.end()})}var q=[8081,8082,8083,8084,8085,8086,3e3,3001,19e3].map(e=>({port:e,pid:0}));function k(e,n){return!(e<=0||e>=2e4||n.has(e)||e>=5170&&e<=5200)}async function Y(e=[]){let n=new Set(e);try{let{stdout:t}=await T("lsof -iTCP -sTCP:LISTEN -P -n 2>/dev/null | grep -E '^(node|bun)'",{encoding:"utf8",timeout:2e3});if(t.trim()){let o=new Map;for(let s of t.trim().split(`
3
3
  `)){let i=s.trim().split(/\s+/);if(i.length<9)continue;let a=Number(i[1]),c=i[8].match(/:(\d+)$/);if(!c)continue;let u=Number(c[1]);k(u,n)&&(o.has(u)||o.set(u,a))}if(o.size>0)return[...o.entries()].map(([s,i])=>({port:s,pid:i}))}}catch{}try{let{stdout:t}=await T(`ss -tlnp 2>/dev/null | grep -E '"(node|bun)"'`,{encoding:"utf8",timeout:2e3});if(t.trim()){let o=new Map;for(let s of t.trim().split(`
4
4
  `)){let i=s.match(/:(\d+)\s/),a=s.match(/pid=(\d+)/);if(!i)continue;let r=Number(i[1]),c=a?Number(a[1]):0;k(r,n)&&(o.has(r)||o.set(r,c))}if(o.size>0)return[...o.entries()].map(([s,i])=>({port:s,pid:i}))}}catch{}return q.filter(t=>k(t.port,n))}var x=new Map;async function Q(e){if(e<=0)return null;let n=x.get(e);if(n)return n;try{let{stdout:t}=await T(`lsof -p ${e} -a -d cwd -Fn 2>/dev/null`,{encoding:"utf8",timeout:1500});for(let o of t.split(`
5
5
  `))if(o.startsWith("n")&&o.length>1){let s=o.slice(1).trim();if(s)return x.set(e,s),s}}catch{}return null}function X(e,n){return{port:e,framework:n,bundleUrl:S(e,`http://localhost:${e}/index.bundle?platform=ios&dev=true&hot=true&minify=false`),hmrUrl:`ws://localhost:${e}/hot`,lastSeen:Date.now()}}function S(e,n){let t=D().find(s=>s.preferredPort===e),o=t?.runtimeConfig?A(n,t.runtimeConfig):n;return I(o)}function Z(e){return e.includes("/node_modules/one/metro-entry.bundle")}function ee(e){try{let n=JSON.parse(e);return n&&typeof n=="object"?n:null}catch{return null}}function w(e,n,t){if(!n)return e;try{let o=JSON.parse(n.body),s=o?.extra?.expoClient||o?.extra||{};s.name&&(e.projectName=s.name),s.ios?.bundleIdentifier&&(e.bundleId=s.ios.bundleIdentifier),e.framework==="metro"&&s.sdkVersion&&(e.framework="expo");let i=o?.launchAsset?.url;i&&!e.patched&&!Z(e.bundleUrl)&&(e.bundleUrl=S(e.port,i));let a=s.iconUrl||s.ios?.iconUrl||s.icon||s.ios?.icon;if(a)if(e.iconPath=a,t)if(a.startsWith("http"))e.iconUrl=t(a);else{let r=a.replace(/^\.\//,"");e.iconUrl=t(`http://localhost:${e.port}/assets/${r}`)}else e.iconUrl=a.startsWith("http")?a:`http://localhost:${e.port}/assets/${a.replace(/^\.\//,"")}`}catch{}return e}var ne=2e4,v=new Map,M=new Set;function _(e,n){if(e.projectName)return e;let t=v.get(e.port);if(t)return t.projectName&&(e.projectName=t.projectName),t.iconUrl&&!e.iconUrl&&(e.iconUrl=t.iconUrl,e.iconPath=t.iconPath),t.bundleId&&!e.bundleId&&(e.bundleId=t.bundleId),e;if(!M.has(e.port)){M.add(e.port);let o=e.port;te(o,n).finally(()=>M.delete(o))}return e}async function te(e,n){let t=await h(e,"/","GET",ne,{"expo-platform":"ios"});if(!t||t.statusCode!==200)return;let o=w({port:e,framework:"one",bundleUrl:"",lastSeen:0},t,n);!o.projectName&&!o.iconUrl||(v.set(e,{projectName:o.projectName,iconUrl:o.iconUrl,iconPath:o.iconPath,bundleId:o.bundleId}),b.delete(e))}var d=new Set,g=new Set,y=new Set;async function oe(e,n){if(!await V(e))return null;let t="/node_modules/one/metro-entry.bundle?platform=ios&dev=true",[o,s,i,a]=await Promise.all([d.has(e)?Promise.resolve(null):h(e,"/__soot/"),h(e,"/status"),y.has(e)?Promise.resolve(null):h(e,"/","GET",J,{"expo-platform":"ios"}),g.has(e)?Promise.resolve(null):h(e,"/_expo/status")]);a&&a.statusCode===200?g.delete(e):g.has(e)||g.add(e);let r=i?ee(i.body):null,c=typeof r?.launchAsset?.url=="string"?r.launchAsset.url:null,u=r?.extra?.expoClient||r?.extra||{};if(r&&(c||typeof u.name=="string")){d.add(e);let U=c||`http://localhost:${e}/index.bundle?platform=ios&dev=true&hot=true&minify=false`,L=U.includes("/one/metro-entry.bundle")?"one":"expo";return w({port:e,framework:L,bundleUrl:S(e,U),hmrUrl:`ws://localhost:${e}/hot`,lastSeen:Date.now()},i,n)}if(s&&s.body.includes("packager-status:running"))return d.add(e),_(w(X(e,a&&a.statusCode===200?"expo":"metro"),i,n),n);if(o&&o.statusCode===200&&o.body.includes("sootsim-patched"))return d.delete(e),_(w({port:e,framework:"one",bundleUrl:S(e,`http://localhost:${e}/__soot/bundle.js`),hmrUrl:`ws://localhost:${e}/hot`,lastSeen:Date.now(),patched:!0},i,n),n);if(s&&s.statusCode===200||a&&a.statusCode===200||i&&i.statusCode===200&&r!=null)return null;let m=await h(e,t,"HEAD");return m&&m.statusCode>0&&m.statusCode<400&&/application\/javascript/i.test(m.contentType||"")?(d.add(e),y.add(e),_(w({port:e,framework:"one",bundleUrl:S(e,`http://localhost:${e}${t}&minify=false`),hmrUrl:`ws://localhost:${e}/hot`,lastSeen:Date.now()},i,n),n)):(d.add(e),null)}function re(e){return!!e.bundleId?.trim().toLowerCase()?.startsWith("dev.sootsim.")}var b=new Map,se=3e4,ie=1500;function ae(e){return!e||e.framework==="metro"||e.framework==="unknown"}function ce(e){return e?S(e.port,e.bundleUrl)===e.bundleUrl:!0}function ue(e,n,t=Date.now()){if(n===0||e.pid!==n||!ce(e.result))return!1;let o=t-e.cachedAt;return!(e.result===null&&o>=se||ae(e.result)&&o>=ie)}async function Pe(e={}){await C();let n=await Y(e.excludePorts),t=new Set(n.map(r=>r.port));for(let r of[...b.keys()])t.has(r)||b.delete(r);for(let r of[...d])t.has(r)||d.delete(r);for(let r of[...g])t.has(r)||g.delete(r);for(let r of[...y])t.has(r)||y.delete(r);for(let r of[...v.keys()])t.has(r)||v.delete(r);let o=[],s=[];for(let{port:r,pid:c}of n){let u=b.get(r);if(u&&ue(u,c)){u.result&&o.push(u.result);continue}u&&u.pid!==c&&(d.delete(r),g.delete(r),y.delete(r),v.delete(r)),s.push({port:r,pid:c})}s.length>0&&(await Promise.all(s.map(c=>oe(c.port,e.buildIconProxyUrl)))).forEach((c,u)=>{let{port:l,pid:m}=s[u];m!==0&&b.set(l,{pid:m,result:c,cachedAt:Date.now()}),c&&o.push(c)});let i=new Map;for(let{port:r,pid:c}of n)c>0&&i.set(r,c);await Promise.all(o.map(async r=>{let c=i.get(r.port);if(!c)return;r.pid=c;let u=await Q(c);u&&(r.cwd=u)}));let a=new Set(i.values());for(let r of[...x.keys()])a.has(r)||x.delete(r);return o.filter(r=>!re(r))}function le(e){return e.replace(/^\[|\]$/g,"").toLowerCase()}function ke(e){let n=le(e);return n==="localhost"||n.endsWith(".localhost")||n==="0.0.0.0"||n==="::1"||/^127(?:\.\d{1,3}){3}$/.test(n)}import R from"fs";import f from"path";import{fileURLToPath as de}from"url";var P;function fe(){if(P!==void 0)return P;let e=f.dirname(de(import.meta.url));for(let n=0;n<12&&e!==f.dirname(e);n++){if(R.existsSync(f.join(e,"packages/sootsim-engine/package.json"))&&R.existsSync(f.join(e,"public/sootsim")))return P=e,e;e=f.dirname(e)}return P=null,null}function Ne(){if(process.env.SOOTSIM_HOME&&E())return null;let e=fe();if(!e)return null;let n=f.join(e,"public/sootsim");return R.existsSync(f.join(n,"index.html"))&&R.existsSync(f.join(n,"engine/index.html"))&&R.existsSync(f.join(n,"engine-tenant/worker.js"))?n:null}export{A as a,pe as b,I as c,ge as d,oe as e,Pe as f,ke as g,Ne as h};
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.270 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{G as N,H as U,I as A,k as $,l as C,u as T,x as V}from"./chunk-557IYHPC.js";import F from"node:fs";import H from"node:path";function D(n){try{return F.readdirSync(n.runtimesDir(),{withFileTypes:!0}).filter(s=>s.isDirectory()).map(s=>s.name).sort(I)}catch{return[]}}function M(n,s){return H.posix.basename(n.tarballPath(s))}function I(n,s){let a=m=>{let d=m.indexOf("-"),p=d>=0?m.slice(0,d):m,x=d>=0?m.slice(d+1):"",b=p.split(".").map(e=>Number.parseInt(e,10));return b.some(e=>!Number.isFinite(e))?[[Number.POSITIVE_INFINITY],m]:[b,x]},[o,c]=a(n),[f,y]=a(s);for(let m=0;m<Math.max(o.length,f.length);m++){let d=o[m]??0,p=f[m]??0;if(d!==p)return d-p}return c===y?0:c?y?c<y?-1:1:-1:1}import{spawn as L}from"node:child_process";import G from"node:crypto";import u from"node:fs";import O from"node:path";import{Readable as z}from"node:stream";import{pipeline as W}from"node:stream/promises";function E(n){function s(){try{let e=JSON.parse(u.readFileSync(n.configFile(),"utf8"));return e&&typeof e=="object"?e:{}}catch{return{}}}function a(e){let t=s();return(e||process.env[n.env.cdnOrigin]||t.cdnOrigin||n.defaultCdnOrigin).replace(/\/+$/,"")}function o(e){let t=s();return e||process.env[n.env.channel]||t.runtimeChannel||"stable"}function c(){let e=process.env[n.env.pin];if(e&&e.trim())return e.trim();let t=s();return typeof t.runtimeVersion=="string"&&t.runtimeVersion.trim()?t.runtimeVersion.trim():null}function f(e){let t=new URL(`${a(e)}${n.manifestPath}`);return t.searchParams.set("t",String(Date.now())),t.toString()}function y(e,t){return`${a(t)}${n.tarballPath(e)}`}async function m(e){let t=f(e),r=await fetch(t,{headers:{Accept:"application/json"}});if(!r.ok)throw new Error(`manifest fetch failed: ${r.status} ${r.statusText} (${t})`);return await r.json()}function d(e,t={}){let r=o(t.channel),i=t.version||c()||e.channels[r]?.latest;if(!i)throw new Error(`no version specified and channel '${r}' has no latest entry in the manifest`);let g=e.versions[i];if(!g)throw new Error(`version ${i} not found in manifest; available: ${Object.keys(e.versions).slice(-10).join(", ")||"(none)"}`);return{version:i,channel:r,entry:g}}async function p(e={}){n.ensureHome();let t=a(e.cdnOrigin),r=await m(t),{version:i,channel:g,entry:l}=d(r,e),v=n.runtimeDir(i),h=e.setActive!==!1;if(!e.force&&u.existsSync(O.join(v,n.installedMarker)))return h&&n.writeActiveRuntime(i),{version:i,channel:g,cdnOrigin:t,runtimeDir:v,installed:!1,activated:h,manifest:r};let P=l.tarball||y(i,t),w=O.join(n.cacheDir(),M(n,i));process.stderr.write(`${n.id}: downloading runtime ${i}\u2026
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{G as N,H as U,I as A,k as $,l as C,u as T,x as V}from"./chunk-QSUJV6FY.js";import F from"node:fs";import H from"node:path";function D(n){try{return F.readdirSync(n.runtimesDir(),{withFileTypes:!0}).filter(s=>s.isDirectory()).map(s=>s.name).sort(I)}catch{return[]}}function M(n,s){return H.posix.basename(n.tarballPath(s))}function I(n,s){let a=m=>{let d=m.indexOf("-"),p=d>=0?m.slice(0,d):m,x=d>=0?m.slice(d+1):"",b=p.split(".").map(e=>Number.parseInt(e,10));return b.some(e=>!Number.isFinite(e))?[[Number.POSITIVE_INFINITY],m]:[b,x]},[o,c]=a(n),[f,y]=a(s);for(let m=0;m<Math.max(o.length,f.length);m++){let d=o[m]??0,p=f[m]??0;if(d!==p)return d-p}return c===y?0:c?y?c<y?-1:1:-1:1}import{spawn as L}from"node:child_process";import G from"node:crypto";import u from"node:fs";import O from"node:path";import{Readable as z}from"node:stream";import{pipeline as W}from"node:stream/promises";function E(n){function s(){try{let e=JSON.parse(u.readFileSync(n.configFile(),"utf8"));return e&&typeof e=="object"?e:{}}catch{return{}}}function a(e){let t=s();return(e||process.env[n.env.cdnOrigin]||t.cdnOrigin||n.defaultCdnOrigin).replace(/\/+$/,"")}function o(e){let t=s();return e||process.env[n.env.channel]||t.runtimeChannel||"stable"}function c(){let e=process.env[n.env.pin];if(e&&e.trim())return e.trim();let t=s();return typeof t.runtimeVersion=="string"&&t.runtimeVersion.trim()?t.runtimeVersion.trim():null}function f(e){let t=new URL(`${a(e)}${n.manifestPath}`);return t.searchParams.set("t",String(Date.now())),t.toString()}function y(e,t){return`${a(t)}${n.tarballPath(e)}`}async function m(e){let t=f(e),r=await fetch(t,{headers:{Accept:"application/json"}});if(!r.ok)throw new Error(`manifest fetch failed: ${r.status} ${r.statusText} (${t})`);return await r.json()}function d(e,t={}){let r=o(t.channel),i=t.version||c()||e.channels[r]?.latest;if(!i)throw new Error(`no version specified and channel '${r}' has no latest entry in the manifest`);let g=e.versions[i];if(!g)throw new Error(`version ${i} not found in manifest; available: ${Object.keys(e.versions).slice(-10).join(", ")||"(none)"}`);return{version:i,channel:r,entry:g}}async function p(e={}){n.ensureHome();let t=a(e.cdnOrigin),r=await m(t),{version:i,channel:g,entry:l}=d(r,e),v=n.runtimeDir(i),h=e.setActive!==!1;if(!e.force&&u.existsSync(O.join(v,n.installedMarker)))return h&&n.writeActiveRuntime(i),{version:i,channel:g,cdnOrigin:t,runtimeDir:v,installed:!1,activated:h,manifest:r};let P=l.tarball||y(i,t),w=O.join(n.cacheDir(),M(n,i));process.stderr.write(`${n.id}: downloading runtime ${i}\u2026
3
3
  `),await J(P,w),process.stderr.write(`${n.id}: extracting runtime ${i}\u2026
4
4
  `);let k=await Y(w);if(k!==l.sha256)throw u.rmSync(w,{force:!0}),new Error(`sha256 mismatch for runtime ${i}: expected ${l.sha256}, actual ${k}`);let R=O.join(O.dirname(v),`.installing-${i}-${process.pid}`);u.rmSync(R,{recursive:!0,force:!0}),u.mkdirSync(R,{recursive:!0});try{if(await q(w,R),!u.existsSync(O.join(R,n.installedMarker)))throw new Error(`extracted tarball for runtime ${i} is missing ${n.installedMarker}`);u.rmSync(v,{recursive:!0,force:!0}),u.renameSync(R,v)}catch(S){throw u.rmSync(R,{recursive:!0,force:!0}),S}return h&&n.writeActiveRuntime(i),{version:i,channel:g,cdnOrigin:t,runtimeDir:v,installed:!0,activated:h,manifest:r}}async function x(e={}){n.ensureHome();let t=a(e.cdnOrigin),r=o(e.channel),i=c();if(i){let S=n.readActiveRuntime(),_=u.existsSync(O.join(n.runtimeDir(i),n.installedMarker));if(S===i&&_)return{checked:!0,updated:!1,reason:`runtime is pinned to ${i}`,activeVersion:S,latestVersion:i};let j=await p({version:i,channel:r,cdnOrigin:t,setActive:!1});return{checked:!0,updated:!0,reason:`runtime is pinned to ${i}`,activeVersion:i,latestVersion:i,install:j}}let g=await m(t),l=g.channels[r]?.latest;if(!l)return{checked:!0,updated:!1,reason:`channel '${r}' has no latest runtime`,activeVersion:n.readActiveRuntime()};if(!g.versions[l])return{checked:!0,updated:!1,reason:`manifest is missing version ${l}`,activeVersion:n.readActiveRuntime(),latestVersion:l};let h=n.readActiveRuntime(),P=h?n.runtimeDir(h):null,w=P?u.existsSync(O.join(P,n.installedMarker)):!1;if(!(!h||!w||I(l,h)>0))return{checked:!0,updated:!1,reason:"active runtime is current",activeVersion:h,latestVersion:l};let R=await p({version:l,channel:r,cdnOrigin:t,setActive:!1});return{checked:!0,updated:!0,activeVersion:l,latestVersion:l,install:R}}async function b(e={}){let t=n.readActiveRuntime(),r=c();if(r)return{active:t,latest:r,pinned:r,outdated:t!==r};try{let i=await m(a(e.cdnOrigin)),g=o(e.channel),l=i.channels[g]?.latest??null,v=!!(l&&(!t||I(l,t)>0));return{active:t,latest:l,pinned:null,outdated:v}}catch{return{active:t,latest:null,pinned:null,outdated:!1}}}return{product:n,resolveCdnOrigin:a,resolveChannel:o,resolvePin:c,manifestUrl:f,tarballUrl:y,fetchManifest:m,resolveVersion:d,install:p,updateToLatest:x,checkUpToDate:b,listInstalled:()=>D(n)}}async function J(n,s){let a=await fetch(n);if(!a.ok||!a.body)throw new Error(`download failed: ${a.status} ${a.statusText} (${n})`);u.mkdirSync(O.dirname(s),{recursive:!0});let o=`${s}.partial`;try{await W(z.fromWeb(a.body),u.createWriteStream(o)),u.renameSync(o,s)}catch(c){try{u.unlinkSync(o)}catch{}throw c}}function Y(n){return new Promise((s,a)=>{let o=G.createHash("sha256"),c=u.createReadStream(n);c.on("data",f=>o.update(f)),c.on("error",a),c.on("end",()=>s(o.digest("hex")))})}function q(n,s){return new Promise((a,o)=>{let c=L("tar",["-xzf",n,"-C",s],{stdio:["ignore","inherit","inherit"]});c.on("error",o),c.on("exit",f=>{f===0?a():o(new Error(`tar exited with code ${f}`))})})}var B="https://contrast.dev",fn="https://sootsim.com/changelog",K={id:"sootsim",defaultCdnOrigin:B,manifestPath:"/runtimes/manifest.json",tarballPath:n=>`/runtimes/sootsim-runtime-${n}.tar.gz`,installedMarker:"index.html",env:{cdnOrigin:"SOOTSIM_CDN_ORIGIN",channel:"SOOTSIM_RUNTIME_CHANNEL",pin:"SOOTSIM_RUNTIME_VERSION"},ensureHome:N,configFile:V,runtimesDir:$,runtimeDir:C,cacheDir:T,readActiveRuntime:U,writeActiveRuntime:A},dn=E(K);export{I as a,B as b,fn as c,dn as d};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.270 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import{createHash as D}from"node:crypto";import y from"node:fs";import{createRequire as I}from"node:module";import h from"node:path";var w=/(^|\/)expo-splash-screen$/,R=/(^|\/)react-native-bootsplash$/;function U(n,e){let r=e.replace(/\/+$/,""),o=n.replace(/^\.\//,"").replace(/^\/+/,"");if(o)return`${r}/assets/${o}`}function d(n,e,r){return r?r(n):U(n,e)}function C(n){if(n==="cover")return"cover";if(n==="contain"||n==="native")return"contain"}function p(n){return typeof n=="string"&&n.length>0?n:void 0}function k(n){return typeof n=="number"&&Number.isFinite(n)?n:void 0}function v(n,e,r){if(!n||typeof n!="object")return null;let o=n,s={source:"expo-splash-screen",backgroundColor:p(o.backgroundColor)??"#ffffff"},l=p(o.image);l&&(s.imageUrl=d(l,e,r));let t=k(o.imageWidth);t!=null&&(s.imageWidthPx=t);let c=C(o.resizeMode);c&&(s.resizeMode=c);let i=o.dark;if(i&&typeof i=="object"){let g=i,u=p(g.backgroundColor),f=p(g.image);(u||f)&&(s.dark={},u&&(s.dark.backgroundColor=u),f&&(s.dark.imageUrl=d(f,e,r)))}return s}function j(n,e,r,o){let a=n[e],s=a&&typeof a=="object"?a.splash:void 0,l=n.splash,t=s&&typeof s=="object"?s:l;if(!t||typeof t!="object")return null;let i={source:"expo-legacy",backgroundColor:p(t.backgroundColor)??"#ffffff",imageWidthPx:k(t.imageWidth)??200,resizeMode:C(t.resizeMode)??"contain"},g=p(t.image);g&&(i.imageUrl=d(g,r,o));let u=t.dark;if(u&&typeof u=="object"){let f=u,S=p(f.backgroundColor),m=p(f.image);(S||m)&&(i.dark={},S&&(i.dark.backgroundColor=S),m&&(i.dark.imageUrl=d(m,r,o)))}return i}function _(n,e,r){if(!n||typeof n!="object")return null;let o=n,a=p(o.logo);if(!a)return null;let s={source:"react-native-bootsplash",backgroundColor:p(o.background)??"#fff",imageUrl:d(a,e,r),imageWidthPx:k(o.logoWidth)??100,resizeMode:"contain"},l=p(o.darkBackground),t=p(o.darkLogo);return(l||t)&&(s.dark={},l&&(s.dark.backgroundColor=l),t&&(s.dark.imageUrl=d(t,e,r))),s}function b(n,e,r,o={}){if(!n||typeof n!="object")return null;let a=n,s=a.plugins,l=null,t=null;if(Array.isArray(s))for(let i of s){let g=Array.isArray(i)?i[0]:i;if(typeof g!="string")continue;let u=Array.isArray(i)?i[1]??{}:{};!l&&w.test(g)?l=v(u,r,o.resolveAssetUrl):!t&&R.test(g)&&(t=_(u,r,o.resolveAssetUrl))}if(l)return l;let c=j(a,e,r,o.resolveAssetUrl);return c||t}var x=I(import.meta.url);function E(n){try{let e=new URL(n),r=e.hostname.replace(/^\[|\]$/g,"").toLowerCase();if(r==="localhost"||r.endsWith(".localhost")||r==="0.0.0.0"||r==="::1"||/^127(?:\.\d{1,3}){3}$/.test(r))return e.origin}catch{}return null}var L=["app.config.js","app.config.ts","app.config.cjs","app.config.mjs","app.json"];function P(n){for(let e of L)try{if(y.statSync(h.join(n,e)).isFile())return!0}catch{}return!1}var F=new Set(["node_modules","artifacts","dist","build","out","coverage","tmp","public","ios","android","macos","windows","__fixtures__","__tests__","examples","example"]);function A(n,e){P(n)&&e.push(n);let r;try{r=y.readdirSync(n,{withFileTypes:!0})}catch{return}for(let o of r)o.isDirectory()&&(o.name.startsWith(".")||F.has(o.name)||A(h.join(n,o.name),e))}function M(n){try{return y.statSync(h.join(n,"package.json")).isFile()}catch{return!1}}function H(n){let e=E(n.bundleUrl);if(!e)return null;let r=n.repoDir||process.env.CONTRAST_REPO_DIR,o=r?h.resolve(r):process.cwd();if(!r&&!M(o))return null;let a=[];if(r)A(o,a),a.includes(o)||a.push(o);else{if(!P(o))return null;a.push(o)}if(a.length===0)return null;let s=(n.platform||process.env.CONTRAST_PLATFORM||"ios").toLowerCase(),l=null;try{let c=x.resolve("@expo/config",{paths:[...a,o]}),i=x(c);typeof i.getConfig=="function"&&(l=i.getConfig)}catch{}if(!l)return null;let t;for(let c of a)try{let i=l(c,{skipSDKVersionRequirement:!0});if(i?.exp&&typeof i.exp=="object"){t=i.exp;break}}catch{}return!t||typeof t!="object"?null:b(t,s==="android"?"android":"ios",e)}function J(n){return encodeURIComponent(JSON.stringify(n))}function z(n){if(!n)return null;try{let e=JSON.parse(decodeURIComponent(n));if(!e||typeof e!="object")return null;let r=e;return r.source!=="expo-splash-screen"&&r.source!=="expo-legacy"&&r.source!=="react-native-bootsplash"||typeof r.backgroundColor!="string"?null:e}catch{return null}}function W(n){let e=new Set;return n.imageUrl&&e.add(n.imageUrl),n.dark?.imageUrl&&e.add(n.dark.imageUrl),[...e]}function N(n){let e=(n.split("?")[0].split(".").pop()||"").toLowerCase();return e==="png"?"image/png":e==="jpg"||e==="jpeg"?"image/jpeg":e==="webp"?"image/webp":e==="gif"?"image/gif":e==="svg"?"image/svg+xml":"application/octet-stream"}async function K(n,e){let r=z(n);if(!r)return[];let o=[],a=new Set;for(let s of W(r)){let l=D("sha256").update(s).digest("hex");if(!a.has(l)){a.add(l);try{let t=await fetch(s);if(!t.ok){e?.onError?.(s,new Error(`${t.status} ${t.statusText}`));continue}let c=new Uint8Array(await t.arrayBuffer());o.push({url:s,urlhash:l,contentType:N(s),bytes:c}),e?.onStaged?.({url:s,byteLength:c.byteLength})}catch(t){e?.onError?.(s,t)}}}return o}export{H as a,J as b,K as c};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.270 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as l}from"./chunk-3VIMSXQZ.js";import{A as o,B as s}from"./chunk-557IYHPC.js";function c(){let e=process.env.DO_NOT_TRACK;return e==="1"||e==="true"||!o()}function p(){if(c())return null;let e=process.env.VITE_POSTHOG_API_KEY||"";if(!e)return null;let t=process.env.CONTRAST_POSTHOG_HOST||process.env.VITE_POSTHOG_HOST||"https://us.i.posthog.com";return{apiKey:e,host:t.replace(/\/+$/,"")}}function u(){try{return s()}catch{return"anonymous-cli"}}function d(e){return e?e.userId?e.userId:e.installationId!=null?`install:${e.installationId}`:e.repoId?`repo:${e.repoId}`:e.shareId?`share:${e.shareId}`:u():u()}function f(e){let t=e.identity??{},n={$lib:"sootsim-cli",source:t.source??"cli",...e.properties};return t.userId&&(n.userId=t.userId),t.repoId&&(n.repoId=t.repoId),t.installationId!=null&&(n.installationId=String(t.installationId)),t.shareId&&(n.shareId=t.shareId),t.plan&&(n.plan=t.plan),{event:e.event,distinct_id:d(t),properties:n,timestamp:new Date().toISOString()}}var r=[],a=!1;async function i(){if(r.length===0)return;let e=p();if(!e){r.length=0;return}let t=r.splice(0,r.length).map(f);try{await fetch(`${e.host}/batch/`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({api_key:e.apiKey,batch:t}),signal:AbortSignal.timeout(2e3)})}catch{}}function I(){a||(a=!0,process.on("beforeExit",()=>void i()),process.on("exit",()=>void i()))}function y(e){if(c())return;I();let t=null;try{t=l()?.user?.id??null}catch{t=null}r.push({...e,identity:{source:"cli",userId:t,...e.identity}})}async function m(){await i()}export{y as a,m as b};
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as l}from"./chunk-RBRFATPJ.js";import{A as o,B as s}from"./chunk-QSUJV6FY.js";function c(){let e=process.env.DO_NOT_TRACK;return e==="1"||e==="true"||!o()}function p(){if(c())return null;let e=process.env.VITE_POSTHOG_API_KEY||"";if(!e)return null;let t=process.env.CONTRAST_POSTHOG_HOST||process.env.VITE_POSTHOG_HOST||"https://us.i.posthog.com";return{apiKey:e,host:t.replace(/\/+$/,"")}}function u(){try{return s()}catch{return"anonymous-cli"}}function d(e){return e?e.userId?e.userId:e.installationId!=null?`install:${e.installationId}`:e.repoId?`repo:${e.repoId}`:e.shareId?`share:${e.shareId}`:u():u()}function f(e){let t=e.identity??{},n={$lib:"sootsim-cli",source:t.source??"cli",...e.properties};return t.userId&&(n.userId=t.userId),t.repoId&&(n.repoId=t.repoId),t.installationId!=null&&(n.installationId=String(t.installationId)),t.shareId&&(n.shareId=t.shareId),t.plan&&(n.plan=t.plan),{event:e.event,distinct_id:d(t),properties:n,timestamp:new Date().toISOString()}}var r=[],a=!1;async function i(){if(r.length===0)return;let e=p();if(!e){r.length=0;return}let t=r.splice(0,r.length).map(f);try{await fetch(`${e.host}/batch/`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({api_key:e.apiKey,batch:t}),signal:AbortSignal.timeout(2e3)})}catch{}}function I(){a||(a=!0,process.on("beforeExit",()=>void i()),process.on("exit",()=>void i()))}function y(e){if(c())return;I();let t=null;try{t=l()?.user?.id??null}catch{t=null}r.push({...e,identity:{source:"cli",userId:t,...e.identity}})}async function m(){await i()}export{y as a,m as b};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.270 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as st}from"./chunk-AMA3YGJ5.js";import{a as it}from"./chunk-GAYG7AO4.js";import{a as ge,c as we,d as be,e as tt,f as ye,g as Se,h as rt,i as ve,j as nt}from"./chunk-B5IBLYEO.js";import{a as et}from"./chunk-SDKIUJUO.js";import{e as ot}from"./chunk-HWGKGIWE.js";import{h as Ye,p as Ze,r as Xe,v as Qe}from"./chunk-SLR3HWMB.js";import{f as je}from"./chunk-FHPXOPMC.js";import{a as qe}from"./chunk-M32JVXHU.js";import{a as We}from"./chunk-FNBFRG64.js";import{h as me,m as Ke}from"./chunk-FCMEOOQE.js";import{I as G,m as Ue,n as Ve,o as Je,p as Ge}from"./chunk-M5VURHXD.js";import{g as he,h as fe,i as ze}from"./chunk-ERXCR7NU.js";import{a as Be,b as ue}from"./chunk-TLNGREAA.js";import{e as pe,f as He}from"./chunk-74HIBIJQ.js";import{a as Le,b as Ne,c as Ce}from"./chunk-PDFKRVDC.js";import*as P from"fs";import{createHash as zt,randomUUID as Kt}from"node:crypto";import{tmpdir as Y}from"os";import*as w from"path";import*as v from"fs";import*as S from"path";var Pt="inset 0 0 0 0.5px #000, inset 0 0 0 2px #757575, inset 0 0 0 5px #212121",lt=1;function kt(i){let e=Ce(i),t=e.scale,r=e.statusBarHeight>0&&!e.dynamicIsland&&e.homeIndicatorHeight===0&&e.cornerRadius===0,n=e.width,o=e.height,a=r?e.width+58:e.width+e.bezelWidth*2,s=r?e.height+111+111:e.height+e.bezelWidth*2,l=9.5,p=lt,u=a+l*2,m=s+lt*2,b=l+(r?29:e.bezelWidth),g=r?111:e.bezelWidth,I=Le(e),k=r?52:I.frameRadius,H=[{side:"right",top:e.hardwareButtons.lock.top,height:e.hardwareButtons.lock.height,width:e.hardwareButtons.width},{side:"left",top:e.hardwareButtons.ringToggle.top,height:e.hardwareButtons.ringToggle.height,width:e.hardwareButtons.width},{side:"left",top:e.hardwareButtons.volumeUp.top,height:e.hardwareButtons.volumeUp.height,width:e.hardwareButtons.width},{side:"left",top:e.hardwareButtons.volumeDown.top,height:e.hardwareButtons.volumeDown.height,width:e.hardwareButtons.width}];return{model:i,renderScale:t,outerWidth:Math.round(u*t),outerHeight:Math.round(m*t),logicalOuterWidth:u,logicalOuterHeight:m,logicalFrameWidth:a,logicalFrameHeight:s,logicalFrameLeft:l,logicalFrameTop:p,logicalScreenWidth:n,logicalScreenHeight:o,logicalScreenLeft:b,logicalScreenTop:g,logicalScreenRadius:r?0:I.screenRadius,logicalFrameRadius:k,frameBackground:r?"linear-gradient(180deg, #1b1c20 0%, #0f1012 42%, #050608 100%)":"#000000",frameOutline:r?"0 0 0 1px #1f2125":"0 0 0 1px #333",metallicRingShadow:r?null:Pt,buttons:H,legacyHomeButton:r?{top:111+e.height+47/2,left:e.width/2-64/2+29,size:64,ring:1.5}:null,showHomeIndicator:e.homeIndicatorHeight>0,logicalHomeIndicatorStripHeight:e.homeIndicatorHeight}}function At(i){let e=i.side==="right",t=e?"inset(-3px -3px -3px 0)":"inset(-3px 0 -3px -3px)";return`
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as st}from"./chunk-V6JB3XB7.js";import{a as it}from"./chunk-6GT6YSKU.js";import{a as ge,c as we,d as ye,e as tt,f as be,g as Se,h as rt,i as ve,j as nt}from"./chunk-53YHX2QG.js";import{a as et}from"./chunk-WIYFHKRE.js";import{e as ot}from"./chunk-MVXVG2BX.js";import{h as Ye,p as Ze,r as Xe,v as Qe}from"./chunk-KQTMW2VR.js";import{f as Ue}from"./chunk-WOLESEXG.js";import{a as ze}from"./chunk-DDVJQ7KL.js";import{a as We}from"./chunk-KNBKEQMZ.js";import{h as me,m as qe}from"./chunk-4SRHESEZ.js";import{I as G,m as je,n as Ve,o as Je,p as Ge}from"./chunk-FLCWG5TT.js";import{g as he,h as fe,i as Ke}from"./chunk-UTYJQ65T.js";import{a as Be,b as ue}from"./chunk-Z6WIJUFD.js";import{e as pe,f as He}from"./chunk-NXJIRSYB.js";import{a as Le,b as Ne,c as Ce}from"./chunk-RVATR53A.js";import*as $ from"fs";import{createHash as Kt,randomUUID as qt}from"node:crypto";import{tmpdir as Y}from"os";import*as w from"path";import*as v from"fs";import*as S from"path";var Pt="inset 0 0 0 0.5px #000, inset 0 0 0 2px #757575, inset 0 0 0 5px #212121",lt=1;function kt(i){let e=Ce(i),t=e.scale,r=e.statusBarHeight>0&&!e.dynamicIsland&&e.homeIndicatorHeight===0&&e.cornerRadius===0,n=e.width,o=e.height,a=Le(e),s=r?e.width+58:a.frameWidth,l=r?e.height+111+111:a.frameHeight,p=9.5,u=lt,m=s+p*2,y=l+lt*2,g=p+(r?29:a.screenLeft),P=r?111:a.screenTop,k=r?52:a.frameRadius,H=[{side:e.hardwareButtons.lock.side,top:e.hardwareButtons.lock.top,height:e.hardwareButtons.lock.height,width:e.hardwareButtons.width},{side:e.hardwareButtons.ringToggle.side,top:e.hardwareButtons.ringToggle.top,height:e.hardwareButtons.ringToggle.height,width:e.hardwareButtons.width},{side:e.hardwareButtons.volumeUp.side,top:e.hardwareButtons.volumeUp.top,height:e.hardwareButtons.volumeUp.height,width:e.hardwareButtons.width},{side:e.hardwareButtons.volumeDown.side,top:e.hardwareButtons.volumeDown.top,height:e.hardwareButtons.volumeDown.height,width:e.hardwareButtons.width}];return{model:i,renderScale:t,outerWidth:Math.round(m*t),outerHeight:Math.round(y*t),logicalOuterWidth:m,logicalOuterHeight:y,logicalFrameWidth:s,logicalFrameHeight:l,logicalFrameLeft:p,logicalFrameTop:u,logicalScreenWidth:n,logicalScreenHeight:o,logicalScreenLeft:g,logicalScreenTop:P,logicalScreenRadius:r?0:a.screenRadius,logicalFrameRadius:k,frameBackground:r?"linear-gradient(180deg, #1b1c20 0%, #0f1012 42%, #050608 100%)":"#000000",frameOutline:r?"0 0 0 1px #1f2125":"0 0 0 1px #333",metallicRingShadow:r?null:Pt,buttons:H,legacyHomeButton:r?{top:111+e.height+47/2,left:e.width/2-64/2+29,size:64,ring:1.5}:null,showHomeIndicator:e.homeIndicatorHeight>0,logicalHomeIndicatorStripHeight:e.homeIndicatorHeight}}function At(i){let e=i.side==="right",t=e?"inset(-3px -3px -3px 0)":"inset(-3px 0 -3px -3px)";return`
3
3
  <div
4
4
  aria-hidden="true"
5
5
  style="
@@ -199,7 +199,7 @@ process.stdin.on('end', async () => {
199
199
  process.exitCode = 1;
200
200
  }
201
201
  });
202
- `;function z(i,e,t){if(t?.multipartForm)throw new Error("http: multipartForm is not supported by sootsim yet");let r={...process.env};for(let s of Object.keys(r))(s.startsWith("BUN_INSPECT")||s==="NODE_OPTIONS")&&delete r[s];let n=_t(process.execPath,["-e",Dt],{input:JSON.stringify({url:i,method:e,headers:t?.headers,body:t?.body}),encoding:"utf8",timeout:Ot,maxBuffer:64*1024*1024,env:r});if(n.error)throw new Error(`http ${e} ${i} failed: ${n.error.message}`);let o;try{o=JSON.parse(n.stdout||"")}catch{throw new Error(`http ${e} ${i} failed: no response (${(n.stderr||"").trim().slice(0,200)})`)}let a=o;if(a.__error)throw new Error(`http ${e} ${i} failed: ${a.__error}`);return a}var Bt=/(?<!\\)\$\{([^$]*)\}/g,Lt=/\\(\$\{[^$]*\})/g,Nt=/^[A-Za-z_$][A-Za-z0-9_$]*$/,ee=class{context;envBinding=new Map;envScopeStack=[];syncedEnvKeys=new Set;output={};maestro;constructor(e={}){this.maestro={copiedText:null,platform:e.platform??"ios"};let t=e.onLog??(n=>console.log(`[flow] js: ${n}`)),r={output:this.output,maestro:this.maestro,http:{get:(n,o)=>z(n,"GET",o),post:(n,o)=>z(n,"POST",o),put:(n,o)=>z(n,"PUT",o),delete:(n,o)=>z(n,"DELETE",o),request:(n,o)=>z(n,(o?.method??"GET").toUpperCase(),o)},console:{log:(...n)=>t(n.map(o=>typeof o=="string"?o:dt(o)).join(" "))}};this.context=N.createContext(r),N.runInContext(`
202
+ `;function K(i,e,t){if(t?.multipartForm)throw new Error("http: multipartForm is not supported by sootsim yet");let r={...process.env};for(let s of Object.keys(r))(s.startsWith("BUN_INSPECT")||s==="NODE_OPTIONS")&&delete r[s];let n=_t(process.execPath,["-e",Dt],{input:JSON.stringify({url:i,method:e,headers:t?.headers,body:t?.body}),encoding:"utf8",timeout:Ot,maxBuffer:64*1024*1024,env:r});if(n.error)throw new Error(`http ${e} ${i} failed: ${n.error.message}`);let o;try{o=JSON.parse(n.stdout||"")}catch{throw new Error(`http ${e} ${i} failed: no response (${(n.stderr||"").trim().slice(0,200)})`)}let a=o;if(a.__error)throw new Error(`http ${e} ${i} failed: ${a.__error}`);return a}var Bt=/(?<!\\)\$\{([^$]*)\}/g,Lt=/\\(\$\{[^$]*\})/g,Nt=/^[A-Za-z_$][A-Za-z0-9_$]*$/,ee=class{context;envBinding=new Map;envScopeStack=[];syncedEnvKeys=new Set;output={};maestro;constructor(e={}){this.maestro={copiedText:null,platform:e.platform??"ios"};let t=e.onLog??(n=>console.log(`[flow] js: ${n}`)),r={output:this.output,maestro:this.maestro,http:{get:(n,o)=>K(n,"GET",o),post:(n,o)=>K(n,"POST",o),put:(n,o)=>K(n,"PUT",o),delete:(n,o)=>K(n,"DELETE",o),request:(n,o)=>K(n,(o?.method??"GET").toUpperCase(),o)},console:{log:(...n)=>t(n.map(o=>typeof o=="string"?o:dt(o)).join(" "))}};this.context=N.createContext(r),N.runInContext(`
203
203
  globalThis.__maestroScope = new Proxy(globalThis, {
204
204
  has() { return true },
205
205
  get(target, key) { return target[key] },
@@ -210,7 +210,7 @@ process.stdin.on('end', async () => {
210
210
  var yPercent = Math.ceil(y * 100) + '%'
211
211
  return xPercent + ',' + yPercent
212
212
  }
213
- `,this.context);for(let[n,o]of Object.entries(process.env))o!==void 0&&this.envBinding.set(n,o)}putEnv(e,t){this.envBinding.set(e,t)}setCopiedText(e){this.maestro.copiedText=e}enterEnvScope(){this.envScopeStack.push(new Map(this.envBinding))}leaveEnvScope(){let e=this.envScopeStack.pop();if(e){this.envBinding.clear();for(let[t,r]of e)this.envBinding.set(t,r)}}evaluate(e,t={}){let r=t.env;if(r&&Object.keys(r).length>0){this.enterEnvScope();try{for(let[n,o]of Object.entries(r))this.envBinding.set(n,o);return this.evalRaw(e)}finally{this.leaveEnvScope()}}return this.evalRaw(e)}evalRaw(e){this.syncEnvToContext();let t=e.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"\\${");return N.runInContext(`(function(){ with(__maestroScope){ return eval(\`${t}\`) } })()`,this.context)}syncEnvToContext(){let e=N.runInContext("globalThis",this.context);for(let t of this.syncedEnvKeys)this.envBinding.has(t)||delete e[t];this.syncedEnvKeys=new Set;for(let[t,r]of this.envBinding)try{e[t]=r,this.syncedEnvKeys.add(t)}catch{}}evaluateStringTemplate(e){return e.replace(Bt,(r,n)=>{if(n.trim().length===0)return"";let o=this.evaluate(n);if(o===void 0&&Nt.test(n.trim()))throw new Error(`missing variable for flow placeholder: ${n.trim()}`);return dt(o)}).replace(Lt,(r,n)=>n)}interpolateStep(e){return this.interpolateValue(e,null)}interpolateValue(e,t){return typeof e=="string"?t==="evalScript"?e:this.evaluateStringTemplate(e):Array.isArray(e)?t==="commands"||t==="onFlowStart"||t==="onFlowComplete"?e:e.map(r=>this.interpolateValue(r,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,n])=>[r,this.interpolateValue(n,r)])):e}};function dt(i){if(i===void 0)return"undefined";if(i===null)return"null";if(typeof i=="object")try{return JSON.stringify(i)}catch{return String(i)}return String(i)}function ut(i){if(i==null)return!1;if(typeof i=="boolean")return i;let e=String(i);if(e.trim().length===0||e.toLowerCase()==="false"||e==="undefined"||e==="null")return!1;let t=Number(e);return!(!Number.isNaN(t)&&t===0)}var te=1e4,Ct=Math.min(10,Math.max(1,Number(process.env.SOOTSIM_FLOW_TIMEOUT_SCALE)||1)),K=i=>Math.round(i*Ct),ne=393,C=852;function f(i){return new Promise(e=>setTimeout(e,i))}function Fe(i){return!!(i&&typeof i=="object"&&!Array.isArray(i))}function q(i,e){if(!Fe(i))return null;let t=i[e];return typeof t=="string"&&t.length>0?t:null}function Ht(i,e){return Fe(i)?i[e]===!0:!1}function Wt(i){if(!i)return null;let e=i.recentApps;if(Array.isArray(e))for(let r of e){let n=q(r,"id");if(n)return n}let t=i.surfaceBindings;return q(t,"app:one")||q(t,"app:two")||null}function jt(i){return i?S.basename(i)===".maestro"?S.dirname(i):i:process.cwd()}function Ut(i,e,t){let r=e.endsWith(".png")?e:`${e}.png`;if(S.isAbsolute(r))return r;if(t.mode==="flow"&&/[\\/]/.test(r)){let n=r.startsWith("./")||r.startsWith("../")?t.flowDir??process.cwd():jt(t.flowDir);return S.resolve(n,r)}return S.join(i,r)}function Vt(i){if(typeof i=="string")return{path:i,withFrame:!1};let e=i.path?.trim()||i.name?.trim();if(!e)throw new Error("takeScreenshot object form requires path or name");return{path:e,withFrame:i.withFrame===!0,layers:i.layers}}function re(i,e){let[t,r]=i.split(",").map(s=>s.trim()),n=(s,l)=>s.endsWith("%")?Number.parseFloat(s)/100*l:Number.parseFloat(s),o=e?.x??0,a=e?.y??0;return{x:o+n(t,e?.width??ne),y:a+n(r,e?.height??C)}}function pt(i){switch(i){case"back":return{back:!0};case"hideKeyboard":return{hideKeyboard:!0};case"waitForAnimationToEnd":return{waitForAnimationToEnd:!0};case"stopApp":return{stopApp:!0};case"clearState":return{clearState:!0};case"clearKeychain":return{clearKeychain:!0};case"eraseText":return{eraseText:50};case"scroll":case"scrollDown":return{scroll:{direction:"DOWN"}};case"scrollUp":return{scroll:{direction:"UP"}};default:return{[i]:!0}}}function Jt(i){let e=i.split(/^---$/m),t=e.length>1?e[e.length-1]:i,r=et.parse(t);return Array.isArray(r)?r:[]}var ie=class{constructor(e,t){this.bridge=e;this.opts=t}stepDelay=0;js=new ee({platform:"ios",onLog:e=>console.log(`[flow] js: ${e}`)});firstLaunchDone=!1;profilingEnabled=!1;recordingEnabled=!1;recordingAccessChecked=!1;recordingStartedAtMs=null;lastRecordingStartedAtMs=null;lastRecordingDurationMs=null;lastRecordingFrameStats=null;flowTraceSteps=[];lastVisualSettledAtMs=0;simRouteHint=null;lastFailedStep=null;get simId(){return this.opts.simId}setSimRouteHint(e){this.simRouteHint=this.normalizeSimRoute(e)}normalizeSimRoute(e){if(!e)return null;try{let t=new URL(e);t.searchParams.delete("inspectOpen");let r=t.searchParams.toString();return`${t.origin}${t.pathname}${r?`?${r}`:""}`}catch{return e}}async refreshSimId(){if(this.opts.simId)try{let e=await this.bridge.listSims(),t=e.find(l=>l.id===this.opts.simId);if(t&&(this.simRouteHint=this.normalizeSimRoute(t.url||t.origin)),e.find(l=>l.id===this.opts.simId&&l.readyState==="open")||!this.simRouteHint)return;let n=this.simRouteHint&&e.find(l=>l.readyState==="open"&&this.normalizeSimRoute(l.url||l.origin)===this.simRouteHint);if(!n)return;let o=e.find(l=>l.isPrimary&&l.readyState==="open"),a=e.find(l=>l.readyState==="open"),s=n??o??a;s&&(this.opts.simId=s.id,console.log(` [flow] sim rotated to ${s.id}`))}catch{}}async evaluate(e,t){return this.bridge.send({type:"evaluate",simId:this.opts.simId,code:e},t?{timeoutMs:t}:void 0)}async callTest(e,...t){return this.bridge.send({type:"call",simId:this.opts.simId,path:`__sootsimTest.${e}`,args:t})}async waitForTree(e=te){let t=Date.now()+K(e),r=Date.now(),n=null,o=0,a=0,s=-1,l=r;for(;Date.now()<t;){try{let u=await this.evaluate(Ue,8e3);if(o=0,u?.externalError)throw new Error(`app failed to load: ${u.externalError}`);if(u){let m=Date.now();u.nodes!==s&&(s=u.nodes,l=m);let b=u.flag===!0&&Je(u),g=u.flag!==!0&&Ge(u);if((b||g)&&u.externalReady!==!1&&!u.externalError&&!u.loadingText&&m-l>=Ve)return}}catch(u){if(n=u instanceof Error?u:new Error(String(u)),n.message.startsWith("app failed to load:"))throw n;if(o++,o>=4)throw new Error(`target sim is not responding to the bridge (${n.message}). it is likely a stale orphan \u2014 run \`sootsim list\`, then close it with \`sootsim close <id>\` or start a fresh one with \`sootsim open --new <port>\`.`);await this.refreshSimId()}let p=Date.now()-r;p-a>=5e3&&(a=p,console.log(` [flow] waiting for app to be ready\u2026 (${Math.round(p/1e3)}s)`)),await f(500)}throw n?.message.startsWith("app failed to load:")?n:new Error(`app not ready after ${e}ms`)}async ensureRecordingStarted(){if(!this.opts.recordingOutputDir)throw new Error("recording output directory not configured");this.recordingAccessChecked||(this.opts.requireRecordingEntitlement&&await st("flow --video",{originOverride:this.opts.billingOriginOverride,allowGitHubAuth:this.opts.allowGitHubRecording}),this.recordingAccessChecked=!0);let e=Date.now(),t=await this.evaluate(`(() => {
213
+ `,this.context);for(let[n,o]of Object.entries(process.env))o!==void 0&&this.envBinding.set(n,o)}putEnv(e,t){this.envBinding.set(e,t)}setCopiedText(e){this.maestro.copiedText=e}enterEnvScope(){this.envScopeStack.push(new Map(this.envBinding))}leaveEnvScope(){let e=this.envScopeStack.pop();if(e){this.envBinding.clear();for(let[t,r]of e)this.envBinding.set(t,r)}}evaluate(e,t={}){let r=t.env;if(r&&Object.keys(r).length>0){this.enterEnvScope();try{for(let[n,o]of Object.entries(r))this.envBinding.set(n,o);return this.evalRaw(e)}finally{this.leaveEnvScope()}}return this.evalRaw(e)}evalRaw(e){this.syncEnvToContext();let t=e.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"\\${");return N.runInContext(`(function(){ with(__maestroScope){ return eval(\`${t}\`) } })()`,this.context)}syncEnvToContext(){let e=N.runInContext("globalThis",this.context);for(let t of this.syncedEnvKeys)this.envBinding.has(t)||delete e[t];this.syncedEnvKeys=new Set;for(let[t,r]of this.envBinding)try{e[t]=r,this.syncedEnvKeys.add(t)}catch{}}evaluateStringTemplate(e){return e.replace(Bt,(r,n)=>{if(n.trim().length===0)return"";let o=this.evaluate(n);if(o===void 0&&Nt.test(n.trim()))throw new Error(`missing variable for flow placeholder: ${n.trim()}`);return dt(o)}).replace(Lt,(r,n)=>n)}interpolateStep(e){return this.interpolateValue(e,null)}interpolateValue(e,t){return typeof e=="string"?t==="evalScript"?e:this.evaluateStringTemplate(e):Array.isArray(e)?t==="commands"||t==="onFlowStart"||t==="onFlowComplete"?e:e.map(r=>this.interpolateValue(r,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,n])=>[r,this.interpolateValue(n,r)])):e}};function dt(i){if(i===void 0)return"undefined";if(i===null)return"null";if(typeof i=="object")try{return JSON.stringify(i)}catch{return String(i)}return String(i)}function ut(i){if(i==null)return!1;if(typeof i=="boolean")return i;let e=String(i);if(e.trim().length===0||e.toLowerCase()==="false"||e==="undefined"||e==="null")return!1;let t=Number(e);return!(!Number.isNaN(t)&&t===0)}var te=1e4,Ct=Math.min(10,Math.max(1,Number(process.env.SOOTSIM_FLOW_TIMEOUT_SCALE)||1)),q=i=>Math.round(i*Ct),ne=393,C=852;function f(i){return new Promise(e=>setTimeout(e,i))}function Fe(i){return!!(i&&typeof i=="object"&&!Array.isArray(i))}function z(i,e){if(!Fe(i))return null;let t=i[e];return typeof t=="string"&&t.length>0?t:null}function Ht(i,e){return Fe(i)?i[e]===!0:!1}function Wt(i){if(!i)return null;let e=i.recentApps;if(Array.isArray(e))for(let r of e){let n=z(r,"id");if(n)return n}let t=i.surfaceBindings;return z(t,"app:one")||z(t,"app:two")||null}function Ut(i){return i?S.basename(i)===".maestro"?S.dirname(i):i:process.cwd()}function jt(i,e,t){let r=e.endsWith(".png")?e:`${e}.png`;if(S.isAbsolute(r))return r;if(t.mode==="flow"&&/[\\/]/.test(r)){let n=r.startsWith("./")||r.startsWith("../")?t.flowDir??process.cwd():Ut(t.flowDir);return S.resolve(n,r)}return S.join(i,r)}function Vt(i){if(typeof i=="string")return{path:i,withFrame:!1};let e=i.path?.trim()||i.name?.trim();if(!e)throw new Error("takeScreenshot object form requires path or name");return{path:e,withFrame:i.withFrame===!0,layers:i.layers}}function re(i,e){let[t,r]=i.split(",").map(s=>s.trim()),n=(s,l)=>s.endsWith("%")?Number.parseFloat(s)/100*l:Number.parseFloat(s),o=e?.x??0,a=e?.y??0;return{x:o+n(t,e?.width??ne),y:a+n(r,e?.height??C)}}function pt(i){switch(i){case"back":return{back:!0};case"hideKeyboard":return{hideKeyboard:!0};case"waitForAnimationToEnd":return{waitForAnimationToEnd:!0};case"stopApp":return{stopApp:!0};case"clearState":return{clearState:!0};case"clearKeychain":return{clearKeychain:!0};case"eraseText":return{eraseText:50};case"scroll":case"scrollDown":return{scroll:{direction:"DOWN"}};case"scrollUp":return{scroll:{direction:"UP"}};default:return{[i]:!0}}}function Jt(i){let e=i.split(/^---$/m),t=e.length>1?e[e.length-1]:i,r=et.parse(t);return Array.isArray(r)?r:[]}var ie=class{constructor(e,t){this.bridge=e;this.opts=t}stepDelay=0;js=new ee({platform:"ios",onLog:e=>console.log(`[flow] js: ${e}`)});firstLaunchDone=!1;profilingEnabled=!1;recordingEnabled=!1;recordingAccessChecked=!1;recordingStartedAtMs=null;lastRecordingStartedAtMs=null;lastRecordingDurationMs=null;lastRecordingFrameStats=null;flowTraceSteps=[];lastVisualSettledAtMs=0;simRouteHint=null;lastFailedStep=null;get simId(){return this.opts.simId}setSimRouteHint(e){this.simRouteHint=this.normalizeSimRoute(e)}normalizeSimRoute(e){if(!e)return null;try{let t=new URL(e);t.searchParams.delete("inspectOpen");let r=t.searchParams.toString();return`${t.origin}${t.pathname}${r?`?${r}`:""}`}catch{return e}}async refreshSimId(){if(this.opts.simId)try{let e=await this.bridge.listSims(),t=e.find(l=>l.id===this.opts.simId);if(t&&(this.simRouteHint=this.normalizeSimRoute(t.url||t.origin)),e.find(l=>l.id===this.opts.simId&&l.readyState==="open")||!this.simRouteHint)return;let n=this.simRouteHint&&e.find(l=>l.readyState==="open"&&this.normalizeSimRoute(l.url||l.origin)===this.simRouteHint);if(!n)return;let o=e.find(l=>l.isPrimary&&l.readyState==="open"),a=e.find(l=>l.readyState==="open"),s=n??o??a;s&&(this.opts.simId=s.id,console.log(` [flow] sim rotated to ${s.id}`))}catch{}}async evaluate(e,t){return this.bridge.send({type:"evaluate",simId:this.opts.simId,code:e},t?{timeoutMs:t}:void 0)}async callTest(e,...t){return this.bridge.send({type:"call",simId:this.opts.simId,path:`__sootsimTest.${e}`,args:t})}async waitForTree(e=te){let t=Date.now()+q(e),r=Date.now(),n=null,o=0,a=0,s=-1,l=r;for(;Date.now()<t;){try{let u=await this.evaluate(je,8e3);if(o=0,u?.externalError)throw new Error(`app failed to load: ${u.externalError}`);if(u){let m=Date.now();u.nodes!==s&&(s=u.nodes,l=m);let y=u.flag===!0&&Je(u),g=u.flag!==!0&&Ge(u);if((y||g)&&u.externalReady!==!1&&!u.externalError&&!u.loadingText&&m-l>=Ve)return}}catch(u){if(n=u instanceof Error?u:new Error(String(u)),n.message.startsWith("app failed to load:"))throw n;if(o++,o>=4)throw new Error(`target sim is not responding to the bridge (${n.message}). it is likely a stale orphan \u2014 run \`sootsim list\`, then close it with \`sootsim close <id>\` or start a fresh one with \`sootsim open --new <port>\`.`);await this.refreshSimId()}let p=Date.now()-r;p-a>=5e3&&(a=p,console.log(` [flow] waiting for app to be ready\u2026 (${Math.round(p/1e3)}s)`)),await f(500)}throw n?.message.startsWith("app failed to load:")?n:new Error(`app not ready after ${e}ms`)}async ensureRecordingStarted(){if(!this.opts.recordingOutputDir)throw new Error("recording output directory not configured");this.recordingAccessChecked||(this.opts.requireRecordingEntitlement&&await st("flow --video",{originOverride:this.opts.billingOriginOverride,allowGitHubAuth:this.opts.allowGitHubRecording}),this.recordingAccessChecked=!0);let e=Date.now(),t=await this.evaluate(`(() => {
214
214
  const rec = window.__sootsimRecorder
215
215
  if (!rec) return { ok: false, error: 'recorder unavailable on this page' }
216
216
  const format = ${JSON.stringify(this.opts.recordingFormat??"webm")}
@@ -386,7 +386,7 @@ process.stdin.on('end', async () => {
386
386
  visible: !!keyboard?.isVisible?.(),
387
387
  focused: !!test?.isTextInputFocused?.(),
388
388
  }
389
- })()`);if(!t?.visible&&!t?.focused){await f(80);return}await f(80)}}async eraseText(e){for(let t=0;t<e;t++)await this.bridge.send({type:"keyboard",simId:this.opts.simId,action:"dispatchKey",text:"Backspace"});await f(100)}async waitFor(e){let t=Date.now()+K(e.timeout||te);for(;Date.now()<t;){if(await this.findElement(e))return;await f(200)}let r=await this.findElement(e),n=r?` (matched node y=${Math.round(r.absolutePosition.y)} \u2014 still off-screen at deadline)`:"";throw new Error(`waitFor: ${JSON.stringify(e)} not found after ${e.timeout||te}ms${n}`)}async takeScreenshot(e){if(!this.hasFreshVisualSettle())try{await this.waitForVisualSettle(),await f(250)}catch{}let t=Vt(e),r=Ut(this.opts.screenshotDir,t.path,{mode:this.opts.screenshotPathMode??"dir",flowDir:this.opts.flowDir});v.mkdirSync(S.dirname(r),{recursive:!0});let n=t.layers??this.opts.screenshotLayers,o={type:"screenshot",simId:this.opts.simId};n&&n!=="full"&&(o.layers=n);let s=(await this.bridge.send(o)).replace(/^data:image\/png;base64,/,""),l=Buffer.from(s,"base64");if(t.withFrame){let p=await this.readCurrentDeviceModel();if(!p)throw new Error("could not read current device model for framed screenshot");let u=await ct(l,p);return v.writeFileSync(r,u),console.log(`[flow] screenshot: ${r} (frame: ${p})`),r}return v.writeFileSync(r,l),console.log(`[flow] screenshot: ${r}`),r}async readCurrentDeviceModel(){let e=await this.bridge.send({type:"call",simId:this.opts.simId,path:"SootSim.bridges.settings.get",args:[]}),t=e&&typeof e.deviceModel=="string"?e.deviceModel:null;return!t||!(t in Ne)?null:t}async captureScreenshot(e){v.mkdirSync(S.dirname(e),{recursive:!0});let r=(await this.bridge.send({type:"screenshot",simId:this.opts.simId})).replace(/^data:image\/png;base64,/,"");v.writeFileSync(e,Buffer.from(r,"base64"))}async captureFailureBundle(e,t){v.mkdirSync(e,{recursive:!0});let r=(u,m)=>{try{v.writeFileSync(S.join(e,u),m)}catch{}},n=async u=>{try{return await this.bridge.send({type:"evaluate",simId:this.opts.simId,code:u})}catch{return null}},o=await n(`(async () => {
389
+ })()`);if(!t?.visible&&!t?.focused){await f(80);return}await f(80)}}async eraseText(e){for(let t=0;t<e;t++)await this.bridge.send({type:"keyboard",simId:this.opts.simId,action:"dispatchKey",text:"Backspace"});await f(100)}async waitFor(e){let t=Date.now()+q(e.timeout||te);for(;Date.now()<t;){if(await this.findElement(e))return;await f(200)}let r=await this.findElement(e),n=r?` (matched node y=${Math.round(r.absolutePosition.y)} \u2014 still off-screen at deadline)`:"";throw new Error(`waitFor: ${JSON.stringify(e)} not found after ${e.timeout||te}ms${n}`)}async takeScreenshot(e){if(!this.hasFreshVisualSettle())try{await this.waitForVisualSettle(),await f(250)}catch{}let t=Vt(e),r=jt(this.opts.screenshotDir,t.path,{mode:this.opts.screenshotPathMode??"dir",flowDir:this.opts.flowDir});v.mkdirSync(S.dirname(r),{recursive:!0});let n=t.layers??this.opts.screenshotLayers,o={type:"screenshot",simId:this.opts.simId};n&&n!=="full"&&(o.layers=n);let s=(await this.bridge.send(o)).replace(/^data:image\/png;base64,/,""),l=Buffer.from(s,"base64");if(t.withFrame){let p=await this.readCurrentDeviceModel();if(!p)throw new Error("could not read current device model for framed screenshot");let u=await ct(l,p);return v.writeFileSync(r,u),console.log(`[flow] screenshot: ${r} (frame: ${p})`),r}return v.writeFileSync(r,l),console.log(`[flow] screenshot: ${r}`),r}async readCurrentDeviceModel(){let e=await this.bridge.send({type:"call",simId:this.opts.simId,path:"SootSim.bridges.settings.get",args:[]}),t=e&&typeof e.deviceModel=="string"?e.deviceModel:null;return!t||!(t in Ne)?null:t}async captureScreenshot(e){v.mkdirSync(S.dirname(e),{recursive:!0});let r=(await this.bridge.send({type:"screenshot",simId:this.opts.simId})).replace(/^data:image\/png;base64,/,"");v.writeFileSync(e,Buffer.from(r,"base64"))}async captureFailureBundle(e,t){v.mkdirSync(e,{recursive:!0});let r=(u,m)=>{try{v.writeFileSync(S.join(e,u),m)}catch{}},n=async u=>{try{return await this.bridge.send({type:"evaluate",simId:this.opts.simId,code:u})}catch{return null}},o=await n(`(async () => {
390
390
  const out = {
391
391
  simId: window.__sootsimBridge?.id ?? window.SootSim?.state?.simId ?? null,
392
392
  url: location.href,
@@ -441,7 +441,7 @@ process.stdin.on('end', async () => {
441
441
  ${e.steps||12}, ${e.stepMs||16}
442
442
  )
443
443
  return { ok: !!ok, reason: ok ? null : 'pinch returned false' }
444
- })()`);if(!t?.ok)throw new Error(`pinch failed: ${t?.reason||"unknown error"}`);await f(250)}async dumpTree(e=6){let t=await this.bridge.send({type:"tree",simId:this.opts.simId,depth:e});return console.log("[flow] tree:"),console.log(typeof t=="string"?t:JSON.stringify(t,null,2)),typeof t=="string"?t:JSON.stringify(t)}async assertTreeContains(e){if(!(await this.dumpTree(8)).includes(e))throw new Error(`assertTreeContains: "${e}" not in tree`)}async waitForAnimationToEnd(e=2e3){let t=Math.max(0,Math.round(e));if(t<=0)return;(await ve({bridge:this.bridge,simId:this.opts.simId,maxMs:t,pollMs:32,stablePolls:2,strict:!0})).settled&&this.markVisualSettled()}async back(){try{await this.tapOn("\u2039")}catch{await this.tapOn("<")}}async scrollUntilVisible(e){let t=Date.now()+(e.timeout||15e3),r=e.direction?.toUpperCase()||"DOWN",n=r==="DOWN"?"UP":r==="UP"?"DOWN":r;for(;Date.now()<t;){let o=await this.findElement({text:e.element});if(o&&o.absolutePosition.y>=0&&o.absolutePosition.y+o.layout.height>0&&o.absolutePosition.y<C-50){if(e.centerElement){let a=C/2,s=o.absolutePosition.y-a;if(Math.abs(s)>100){let l=Math.min(150,Math.abs(s)*.5),p=s>0?a-l:a+l;await this.drag(ne/2,a,ne/2,p,10,16)}}return}await this.swipe(n,250),await f(500)}throw new Error(`scrollUntilVisible: "${e.element}" not found`)}async extendedWaitUntil(e){let t=Date.now()+K(e.timeout||te);for(;Date.now()<t;){let r=e.visible?await this.isElementVisible(typeof e.visible=="string"?{text:e.visible}:e.visible):!0,n=e.notVisible?!await this.isElementVisible(typeof e.notVisible=="string"?{text:e.notVisible}:e.notVisible):!0;if(r&&n)return;await f(200)}throw new Error("extendedWaitUntil timed out")}async reloadGuestApp(e){if(e){let n=!1;for(let o=0;o<3&&!n;o++)try{n=await this.evaluate(ge(!0),2e4)}catch{await f(1e3)}n||console.warn(" warn: tenant storage clear did not ack \u2014 hard-reloading anyway (worker reset follows)")}await this.evaluate("window.location.reload()").catch(()=>{}),await f(500),await this.refreshSimId()}async softReloadGuestApp(e){if(!await this.evaluate(ge(e),12e4))throw new Error("guest app soft reload bridge unavailable")}async rearmCaptureAfterRuntimeReload(){if(!this.recordingEnabled&&!this.profilingEnabled)return;let e=Date.now()+1e4,t=null;for(;Date.now()<e;){await this.refreshSimId();try{this.recordingEnabled&&await this.ensureRecordingStarted(),this.profilingEnabled&&await this.startProfile();return}catch(r){t=r,await f(250)}}throw new Error(`capture re-arm failed after app reload: ${t instanceof Error?t.message:String(t)}`)}async launchApp(e){await this.refreshSimId(),e&&typeof e=="object"&&e.arguments&&console.log("[flow] launchApp.arguments ignored (sootsim has no native process)");let t=!!(e&&typeof e=="object"&&e.clearState),r=Ht(e,"resetRuntime");if(!this.firstLaunchDone&&!t){if(this.firstLaunchDone=!0,r){let n=await G(this.bridge).catch(()=>null),o=n?.state==="home"&&n.activeApp==null;await this.softReloadGuestApp(!1),await this.waitForTree(12e4),o&&(await me(this.bridge,"goHome",1e3),await this.waitForShellHome(1e3)),await this.launchShellAppFromHomeIfNeeded(e,o?{...n??{},state:"home",activeApp:null}:null)}else await this.launchShellAppFromHomeIfNeeded(e);await this.waitForTree(3e4)}else if(this.firstLaunchDone=!0,await this.reloadGuestApp(t),await this.waitForTree(12e4),this.opts.onAfterLaunch)try{await this.opts.onAfterLaunch()}catch(n){console.warn(` warn: onAfterLaunch hook threw: ${n instanceof Error?n.message:n}`)}this.profilingEnabled&&await this.startProfile(),this.recordingEnabled&&(await this.waitForVisualSettle(),await this.ensureRecordingStarted())}async waitForVisualSettle(){try{await this.evaluate(`new Promise((resolve) => {
444
+ })()`);if(!t?.ok)throw new Error(`pinch failed: ${t?.reason||"unknown error"}`);await f(250)}async dumpTree(e=6){let t=await this.bridge.send({type:"tree",simId:this.opts.simId,depth:e});return console.log("[flow] tree:"),console.log(typeof t=="string"?t:JSON.stringify(t,null,2)),typeof t=="string"?t:JSON.stringify(t)}async assertTreeContains(e){if(!(await this.dumpTree(8)).includes(e))throw new Error(`assertTreeContains: "${e}" not in tree`)}async waitForAnimationToEnd(e=2e3){let t=Math.max(0,Math.round(e));if(t<=0)return;(await ve({bridge:this.bridge,simId:this.opts.simId,maxMs:t,pollMs:32,stablePolls:2,strict:!0})).settled&&this.markVisualSettled()}async back(){try{await this.tapOn("\u2039")}catch{await this.tapOn("<")}}async scrollUntilVisible(e){let t=Date.now()+(e.timeout||15e3),r=e.direction?.toUpperCase()||"DOWN",n=r==="DOWN"?"UP":r==="UP"?"DOWN":r;for(;Date.now()<t;){let o=await this.findElement({text:e.element});if(o&&o.absolutePosition.y>=0&&o.absolutePosition.y+o.layout.height>0&&o.absolutePosition.y<C-50){if(e.centerElement){let a=C/2,s=o.absolutePosition.y-a;if(Math.abs(s)>100){let l=Math.min(150,Math.abs(s)*.5),p=s>0?a-l:a+l;await this.drag(ne/2,a,ne/2,p,10,16)}}return}await this.swipe(n,250),await f(500)}throw new Error(`scrollUntilVisible: "${e.element}" not found`)}async extendedWaitUntil(e){let t=Date.now()+q(e.timeout||te);for(;Date.now()<t;){let r=e.visible?await this.isElementVisible(typeof e.visible=="string"?{text:e.visible}:e.visible):!0,n=e.notVisible?!await this.isElementVisible(typeof e.notVisible=="string"?{text:e.notVisible}:e.notVisible):!0;if(r&&n)return;await f(200)}throw new Error("extendedWaitUntil timed out")}async reloadGuestApp(e){if(e){let n=!1;for(let o=0;o<3&&!n;o++)try{n=await this.evaluate(ge(!0),2e4)}catch{await f(1e3)}n||console.warn(" warn: tenant storage clear did not ack \u2014 hard-reloading anyway (worker reset follows)")}await this.evaluate("window.location.reload()").catch(()=>{}),await f(500),await this.refreshSimId()}async softReloadGuestApp(e){if(!await this.evaluate(ge(e),12e4))throw new Error("guest app soft reload bridge unavailable")}async rearmCaptureAfterRuntimeReload(){if(!this.recordingEnabled&&!this.profilingEnabled)return;let e=Date.now()+1e4,t=null;for(;Date.now()<e;){await this.refreshSimId();try{this.recordingEnabled&&await this.ensureRecordingStarted(),this.profilingEnabled&&await this.startProfile();return}catch(r){t=r,await f(250)}}throw new Error(`capture re-arm failed after app reload: ${t instanceof Error?t.message:String(t)}`)}async launchApp(e){await this.refreshSimId(),e&&typeof e=="object"&&e.arguments&&console.log("[flow] launchApp.arguments ignored (sootsim has no native process)");let t=!!(e&&typeof e=="object"&&e.clearState),r=Ht(e,"resetRuntime");if(!this.firstLaunchDone&&!t){if(this.firstLaunchDone=!0,r){let n=await G(this.bridge).catch(()=>null),o=n?.state==="home"&&n.activeApp==null;await this.softReloadGuestApp(!1),await this.waitForTree(12e4),o&&(await me(this.bridge,"goHome",1e3),await this.waitForShellHome(1e3)),await this.launchShellAppFromHomeIfNeeded(e,o?{...n??{},state:"home",activeApp:null}:null)}else await this.launchShellAppFromHomeIfNeeded(e);await this.waitForTree(3e4)}else if(this.firstLaunchDone=!0,await this.reloadGuestApp(t),await this.waitForTree(12e4),this.opts.onAfterLaunch)try{await this.opts.onAfterLaunch()}catch(n){console.warn(` warn: onAfterLaunch hook threw: ${n instanceof Error?n.message:n}`)}this.profilingEnabled&&await this.startProfile(),this.recordingEnabled&&(await this.waitForVisualSettle(),await this.ensureRecordingStarted())}async waitForVisualSettle(){try{await this.evaluate(`new Promise((resolve) => {
445
445
  requestAnimationFrame(() => {
446
446
  requestAnimationFrame(() => {
447
447
  requestAnimationFrame(() => {
@@ -449,7 +449,7 @@ process.stdin.on('end', async () => {
449
449
  })
450
450
  })
451
451
  })
452
- })`),this.markVisualSettled()}catch{await f(180),this.markVisualSettled()}}markVisualSettled(){this.lastVisualSettledAtMs=Date.now()}hasFreshVisualSettle(){return Date.now()-this.lastVisualSettledAtMs<750}resolveShellLaunchAppId(e,t){if(typeof e=="string"&&e.length>0)return e;if(Fe(e)){let r=q(e,"appId")||q(e,"id");if(r)return r}return Wt(t)||"connect"}async waitForShellAppLaunched(e,t){let r=Date.now()+t,n=null;for(;Date.now()<r;){try{n=await G(this.bridge)}catch{n=null}if(n?.state==="app"&&n.activeApp===e&&n.showSwitcher===!1&&typeof n.launchProgress=="number"&&n.launchProgress>=.98)return;await f(16)}}async waitForShellHome(e){let t=Date.now()+e;for(;Date.now()<t;){let r=await G(this.bridge).catch(()=>null);if(r?.state==="home"&&r.activeApp==null&&r.showSwitcher===!1)return;await f(16)}}async launchShellAppFromHomeIfNeeded(e,t){let r=null;if(t)r=t;else try{r=await G(this.bridge)}catch{return!1}if(r?.state!=="home"||r.activeApp!=null)return!1;let n=this.resolveShellLaunchAppId(e,r);return this.recordingEnabled&&await this.ensureRecordingStarted(),await me(this.bridge,"launchApp",1e3,n),await this.waitForShellAppLaunched(n,1e3),!0}async startProfile(){let e=await this.evaluate(`(() => {
452
+ })`),this.markVisualSettled()}catch{await f(180),this.markVisualSettled()}}markVisualSettled(){this.lastVisualSettledAtMs=Date.now()}hasFreshVisualSettle(){return Date.now()-this.lastVisualSettledAtMs<750}resolveShellLaunchAppId(e,t){if(typeof e=="string"&&e.length>0)return e;if(Fe(e)){let r=z(e,"appId")||z(e,"id");if(r)return r}return Wt(t)||"connect"}async waitForShellAppLaunched(e,t){let r=Date.now()+t,n=null;for(;Date.now()<r;){try{n=await G(this.bridge)}catch{n=null}if(n?.state==="app"&&n.activeApp===e&&n.showSwitcher===!1&&typeof n.launchProgress=="number"&&n.launchProgress>=.98)return;await f(16)}}async waitForShellHome(e){let t=Date.now()+e;for(;Date.now()<t;){let r=await G(this.bridge).catch(()=>null);if(r?.state==="home"&&r.activeApp==null&&r.showSwitcher===!1)return;await f(16)}}async launchShellAppFromHomeIfNeeded(e,t){let r=null;if(t)r=t;else try{r=await G(this.bridge)}catch{return!1}if(r?.state!=="home"||r.activeApp!=null)return!1;let n=this.resolveShellLaunchAppId(e,r);return this.recordingEnabled&&await this.ensureRecordingStarted(),await me(this.bridge,"launchApp",1e3,n),await this.waitForShellAppLaunched(n,1e3),!0}async startProfile(){let e=await this.evaluate(`(() => {
453
453
  if (!window.__sootsimShellPerf) {
454
454
  return { error: "shell frame profile unavailable (__sootsimShellPerf missing on the page)" }
455
455
  }
@@ -460,7 +460,7 @@ process.stdin.on('end', async () => {
460
460
  return { error: "shell frame profile unavailable (__sootsimShellPerf missing on the page)" }
461
461
  }
462
462
  return await window.__sootsimShellPerf.stop()
463
- })()`);if(this.profilingEnabled=!1,e?.error)throw new Error(e.error);return e}async stopApp(){await this.reloadGuestApp(!1),await this.rearmCaptureAfterRuntimeReload()}async clearState(){await this.reloadGuestApp(!0),await this.rearmCaptureAfterRuntimeReload()}clearKeychain(){console.warn("[flow] clearKeychain: sootsim has no keychain surface \u2014 no-op (warning)")}async copyTextFrom(e){let t=typeof e=="string"?{id:e}:e,r=await this.findElement(t);if(!r)throw new Error(`copyTextFrom: element not found: ${JSON.stringify(t)}`);let n=r.text??r.testID??"";this.js.setCopiedText(n),this.js.putEnv("maestroCopiedText",n),console.log(`[flow] copied text: ${JSON.stringify(n)}`)}evalScript(e){let r=/(?<!\\)\$\{[^$]*\}/.test(e)?this.js.evaluateStringTemplate(e):this.js.evaluate(e);r!==void 0&&r!==""&&console.log("[flow] evalScript ->",r)}runScript(e){let t=typeof e=="string"?{file:e}:e;if(!t.file)throw new Error("runScript requires a file");let r=S.resolve(this.opts.flowDir,t.file),n=v.readFileSync(r,"utf8");this.js.evaluate(n,{env:t.env}),console.log(`[flow] runScript: ${t.file} done`)}async openLink(e){let t=typeof e=="string"?e:e.link;if(!t)throw new Error("openLink: missing link");let r=await this.callTest("openDeepLink",t);if(!r?.ok)throw new Error(`openLink failed: ${r?.error||"no test bridge"}`);await f(300)}async evaluateWhen(e){if(e.visible!==void 0){let t=typeof e.visible=="string"?{text:e.visible}:e.visible;return!!await this.findElement(t)}if(e.notVisible!==void 0){let t=typeof e.notVisible=="string"?{text:e.notVisible}:e.notVisible;return!await this.findElement(t)}return e.platform!==void 0?e.platform.toLowerCase()===this.js.maestro.platform.toLowerCase():e.true!==void 0?ut(e.true):!0}isOptional(e){if(e.optional===!0)return!0;let r=Object.entries(e).find(([o])=>o!=="when"&&o!=="optional"),n=r?r[1]:void 0;return!!(n&&typeof n=="object"&&"optional"in n&&n.optional)}async runStep(e,t){let r=typeof e=="string"?pt(e):e,n=Object.keys(r).find(l=>l!=="when")||Object.keys(r)[0];console.log(`[flow] step ${t+1}: ${n}`);let o=Date.now(),a=this.flowStepTargetLabel(r,n),s;try{s=this.js.interpolateStep(r),a=this.flowStepTargetLabel(s,n)??a}catch(l){if(this.isOptional(r)){console.log(`[flow] (optional, skipped: ${l.message.slice(0,80)})`),this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"skipped",error:l});return}throw this.lastFailedStep={index:t,kind:n,target:r[n]},this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"failure",error:l}),l}if(s.when&&!await this.evaluateWhen(s.when)){console.log("[flow] (when: predicate false, skipped)"),this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"skipped"});return}try{let l=!!(s.extendedWaitUntil||s.waitFor||s.scrollUntilVisible||s.launchApp||s.runFlow||s.runScript),p=1e4,u=this.runStepInner(s),m;if(l){let g=await u;typeof g=="string"&&(m=g)}else{let g=null,I=new Promise((k,H)=>{g=setTimeout(()=>{H(new Error(`step watchdog: ${n} made no progress in ${p}ms \u2014 bridge or bundle probably hung`))},p)});try{let k=await Promise.race([u,I]);typeof k=="string"&&(m=k)}finally{g&&clearTimeout(g)}}let b=!!(s.assertVisible||s.assertNotVisible||s.extendedWaitUntil||s.waitFor);this.stepDelay>0&&!b&&await f(this.stepDelay),this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"success",screenshotPath:m})}catch(l){if(this.isOptional(s)){console.log(`[flow] (optional, skipped: ${l.message.slice(0,80)})`),this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"skipped",error:l});return}throw this.lastFailedStep={index:t,kind:n,target:s[n]},this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"failure",error:l}),l}}async runStepInner(e){if(e.tapOn)await this.tapOn(e.tapOn);else if(e.longPressOn)await this.longPressOn(e.longPressOn);else if(e.scrollUntilVisible)await this.scrollUntilVisible(e.scrollUntilVisible);else if(e.extendedWaitUntil)await this.extendedWaitUntil(e.extendedWaitUntil);else if(e.assertVisible)await this.assertVisible(e.assertVisible);else if(e.assertNotVisible)await this.assertNotVisible(e.assertNotVisible);else if(e.inputText)await this.inputText(e.inputText);else if(e.pressKey)await this.pressKey(e.pressKey);else if(e.dispatchKey)await this.dispatchKey(e.dispatchKey);else if(e.waitFor)await this.waitFor(e.waitFor);else{if(e.takeScreenshot)return this.takeScreenshot(e.takeScreenshot);if(e.swipe)e.swipe.start&&e.swipe.end?await this.swipeCoords(e.swipe.start,e.swipe.end,e.swipe.duration):e.swipe.from?await this.swipeFrom(e.swipe.from,e.swipe.direction,e.swipe.duration):await this.swipe(e.swipe.direction,e.swipe.duration);else if(e.scroll)await this.swipe(e.scroll.direction==="DOWN"?"UP":"DOWN");else if(e.scrollTo){let t=typeof e.scrollTo.nodeId=="number"?{nodeId:e.scrollTo.nodeId}:e.scrollTo.id;if(!t)throw new Error("scrollTo requires id or nodeId");await this.scrollTo(t,e.scrollTo.x,e.scrollTo.y)}else if(e.pinch)await this.pinch(e.pinch);else if(e.waitForAnimationToEnd){let t=e.waitForAnimationToEnd;await this.waitForAnimationToEnd(typeof t=="number"?t:typeof t=="object"&&typeof t.timeout=="number"?t.timeout:2e3)}else if(e.back)await this.back();else if(e.hideKeyboard)await this.hideKeyboard();else if(e.launchApp)await this.launchApp(e.launchApp);else if(typeof e.wait=="number")await f(e.wait);else if(e.dumpTree)await this.dumpTree(e.dumpTree);else if(e.tapAtCoords)await this.tapAtCoords(e.tapAtCoords.x,e.tapAtCoords.y);else if(e.doubleTapAtCoords)await this.doubleTapAtCoords(e.doubleTapAtCoords.x,e.doubleTapAtCoords.y,e.doubleTapAtCoords.gapMs);else if(e.assertTreeContains)await this.assertTreeContains(e.assertTreeContains);else if(typeof e.eraseText=="number")await this.eraseText(e.eraseText);else if(e.repeat&&Array.isArray(e.repeat.commands)){let t=e.repeat.times,r=t==null||t===""?Number.MAX_SAFE_INTEGER:Number(t);if(!Number.isFinite(r))throw new Error(`repeat.times is not a number: ${t}`);let n=e.repeat.when??e.repeat.condition,o=async()=>n?this.evaluateWhen(n):!0,a=n?r:Math.min(r,1e3),s=0;for(;s<a&&await o();){for(let l=0;l<e.repeat.commands.length;l++)await this.runStep(e.repeat.commands[l],l);s++}}else if(e.stopApp!==void 0)await this.stopApp();else if(e.clearState!==void 0)await this.clearState();else if(e.clearKeychain!==void 0)this.clearKeychain();else if(e.copyTextFrom!==void 0)await this.copyTextFrom(e.copyTextFrom);else if(typeof e.evalScript=="string")this.evalScript(e.evalScript);else if(e.runScript){let t=e.runScript,r=typeof t=="string"?void 0:t.when;if(r&&!await this.evaluateWhen(r)){console.log("[flow] runScript skipped (when predicate false)");return}this.runScript(t)}else if(e.openLink!==void 0)await this.openLink(e.openLink);else if(e.runFlow){let t=e.runFlow,r=typeof t=="string"?t:t.file,n=typeof t=="string"?void 0:t.commands,o=typeof t=="string"?void 0:t.env,a=typeof t=="string"?void 0:t.when;if(a&&!await this.evaluateWhen(a)){console.log(`[flow] runFlow skipped (when predicate false): ${r??"inline commands"}`);return}if(!r&&!n)throw new Error("runFlow requires either file or commands");this.js.enterEnvScope();try{if(o)for(let[s,l]of Object.entries(o))this.js.putEnv(s,l);if(r){let s=S.resolve(this.opts.flowDir,r),l=v.readFileSync(s,"utf8"),p=this.opts.flowDir;this.opts.flowDir=S.dirname(s);try{await this.runFlow(Jt(l))}finally{this.opts.flowDir=p}}else if(n)for(let s=0;s<n.length;s++)await this.runStep(n[s],s)}finally{this.js.leaveEnvScope()}}else throw new Error(`unsupported flow step: ${JSON.stringify(e)}`)}}liveStatus=null;async runFlow(e){let t=[],r=[],n=[];for(let a of e){let s=Object.keys(a);if(s.length===1&&s[0]==="onFlowStart"&&Array.isArray(a.onFlowStart)){t.push(...a.onFlowStart);continue}if(s.length===1&&s[0]==="onFlowComplete"&&Array.isArray(a.onFlowComplete)){r.push(...a.onFlowComplete);continue}n.push(a)}if(this.liveStatus&&await this.liveStatus.plan(n.map((a,s)=>{let l=typeof a=="string"?pt(a):a,p=Object.keys(l).find(u=>u!=="when")??Object.keys(l)[0];return{index:s,name:p,target:this.flowStepTargetLabel(l,p)}})),t.length>0){console.log(`[flow] onFlowStart (${t.length} steps)`);for(let a=0;a<t.length;a++)await this.runStep(t[a],a)}let o=null;try{await this.runFlowBody(n)}catch(a){o=a instanceof Error?a:new Error(String(a))}if(r.length>0){console.log(`[flow] onFlowComplete (${r.length} steps)`);for(let a=0;a<r.length;a++)try{await this.runStep(r[a],a)}catch(s){console.warn(`[flow] onFlowComplete step ${a+1} failed: ${s instanceof Error?s.message:s}`)}}if(o)throw o}async runFlowBody(e){for(let t=0;t<e.length;t++){let r=e[t],n=typeof r.wait=="number"?r.wait:0,o=typeof r.waitFor?.timeout=="number"?r.waitFor.timeout:0,a=typeof r.extendedWaitUntil?.timeout=="number"?r.extendedWaitUntil.timeout:0,s=Math.max(6e4,n+15e3,K(o)+15e3,K(a)+15e3);this.liveStatus&&(await this.liveStatus.waitWhilePaused(),await this.liveStatus.step(t,"running"));let l=Date.now(),p=async(u,m)=>{if(!this.liveStatus)return;let b=this.flowTraceSteps[this.flowTraceSteps.length-1],g=b&&b.stepIndex===t&&b.startedAtMs>=l;await this.liveStatus.step(t,u?"failure":g&&b.status==="skipped"?"skipped":"success",{durationMs:Date.now()-l,error:u?m instanceof Error?m.message.slice(0,300):String(m).slice(0,300):g&&b.error||void 0})};try{r.runFlow||r.launchApp?await this.runStep(r,t):await Promise.race([this.runStep(r,t),new Promise((u,m)=>setTimeout(()=>m(new Error(`step ${t+1} (${Object.keys(r)[0]}) exceeded ${s}ms deadline`)),s))])}catch(u){let m=this.flowTraceSteps[this.flowTraceSteps.length-1];if(!(m&&m.stepIndex===t&&m.startedAtMs>=l)){let b=Object.keys(r)[0];this.lastFailedStep={index:t,kind:b,target:r[b]},this.recordFlowTraceStep({stepIndex:t,stepName:b,targetLabel:this.flowStepTargetLabel(r,b),startedAtMs:l,status:"failure",error:u})}throw await p(!0,u),u}await p(!1)}}};function Gt(i){if(typeof i!="object"||i==null||!("control"in i))return!1;let e=i.control;return typeof e=="object"&&e!=null&&"paused"in e&&e.paused===!0}var oe=class{constructor(e,t,r){this.bridge=e;this.flowName=t;this.getSimId=r}disabled=!1;paused=!1;lastSimId;plannedSteps=null;completedSteps=new Map;runId=`flr_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`;async send(e,t){let r=await this.bridge.send({type:"flowStatus",simId:t,status:{runId:this.runId,flowName:this.flowName,...e}});this.paused=Gt(r)}async push(e){if(!this.disabled)try{let t=this.getSimId?.();if(t!==this.lastSimId&&this.lastSimId!=null&&this.plannedSteps&&e.phase!=="plan"){await this.send({phase:"plan",state:"running",steps:this.plannedSteps},t);for(let r of this.completedSteps.values())await this.send({phase:"step",state:"running",step:r},t)}this.lastSimId=t,await this.send(e,t)}catch(t){this.disabled=!0,console.log(`[flow] live status unavailable (${t instanceof Error?t.message.slice(0,120):t}) \u2014 continuing without the devtools rail`)}}async plan(e){this.plannedSteps=e.map(t=>({...t})),this.completedSteps.clear(),await this.push({phase:"plan",state:"running",steps:e})}async step(e,t,r){let n={index:e,status:t,...r};await this.push({phase:"step",state:"running",step:n}),this.completedSteps.set(e,n)}async end(e){await this.push({phase:"end",state:e})}async waitWhilePaused(){if(!this.disabled)for(;this.paused;){for(console.log("[flow] paused from devtools \u2014 waiting\u2026");this.paused&&!this.disabled;)await new Promise(e=>setTimeout(e,400)),await this.push({phase:"heartbeat",state:"paused"});this.disabled||console.log("[flow] resumed")}}};var Ie=null;function Hr(){return Ie}var $e=[];function Wr(){return $e}async function qt(i){if(!i)return"";let e=i.trim();if(!e)return"";if(/^\d+$/.test(e)||e.startsWith("http://")||e.startsWith("https://"))return e;let r=(await We()).find(n=>n.name.toLowerCase()===e.toLowerCase());return r?String(r.preferredPort):e}async function Yt(){let i=await je(),e=i.find(r=>r.patched);if(e)return`http://localhost:${e.port}/__soot/`;let t=i[0];return t?`http://localhost:${t.port}/__soot/`:null}async function ft(i){Ie=null,$e=[],(i.length===0||i.includes("--help")||i.includes("-h"))&&(console.log(`
463
+ })()`);if(this.profilingEnabled=!1,e?.error)throw new Error(e.error);return e}async stopApp(){await this.reloadGuestApp(!1),await this.rearmCaptureAfterRuntimeReload()}async clearState(){await this.reloadGuestApp(!0),await this.rearmCaptureAfterRuntimeReload()}clearKeychain(){console.warn("[flow] clearKeychain: sootsim has no keychain surface \u2014 no-op (warning)")}async copyTextFrom(e){let t=typeof e=="string"?{id:e}:e,r=await this.findElement(t);if(!r)throw new Error(`copyTextFrom: element not found: ${JSON.stringify(t)}`);let n=r.text??r.testID??"";this.js.setCopiedText(n),this.js.putEnv("maestroCopiedText",n),console.log(`[flow] copied text: ${JSON.stringify(n)}`)}evalScript(e){let r=/(?<!\\)\$\{[^$]*\}/.test(e)?this.js.evaluateStringTemplate(e):this.js.evaluate(e);r!==void 0&&r!==""&&console.log("[flow] evalScript ->",r)}runScript(e){let t=typeof e=="string"?{file:e}:e;if(!t.file)throw new Error("runScript requires a file");let r=S.resolve(this.opts.flowDir,t.file),n=v.readFileSync(r,"utf8");this.js.evaluate(n,{env:t.env}),console.log(`[flow] runScript: ${t.file} done`)}async openLink(e){let t=typeof e=="string"?e:e.link;if(!t)throw new Error("openLink: missing link");let r=await this.callTest("openDeepLink",t);if(!r?.ok)throw new Error(`openLink failed: ${r?.error||"no test bridge"}`);await f(300)}async evaluateWhen(e){if(e.visible!==void 0){let t=typeof e.visible=="string"?{text:e.visible}:e.visible;return!!await this.findElement(t)}if(e.notVisible!==void 0){let t=typeof e.notVisible=="string"?{text:e.notVisible}:e.notVisible;return!await this.findElement(t)}return e.platform!==void 0?e.platform.toLowerCase()===this.js.maestro.platform.toLowerCase():e.true!==void 0?ut(e.true):!0}isOptional(e){if(e.optional===!0)return!0;let r=Object.entries(e).find(([o])=>o!=="when"&&o!=="optional"),n=r?r[1]:void 0;return!!(n&&typeof n=="object"&&"optional"in n&&n.optional)}async runStep(e,t){let r=typeof e=="string"?pt(e):e,n=Object.keys(r).find(l=>l!=="when")||Object.keys(r)[0];console.log(`[flow] step ${t+1}: ${n}`);let o=Date.now(),a=this.flowStepTargetLabel(r,n),s;try{s=this.js.interpolateStep(r),a=this.flowStepTargetLabel(s,n)??a}catch(l){if(this.isOptional(r)){console.log(`[flow] (optional, skipped: ${l.message.slice(0,80)})`),this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"skipped",error:l});return}throw this.lastFailedStep={index:t,kind:n,target:r[n]},this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"failure",error:l}),l}if(s.when&&!await this.evaluateWhen(s.when)){console.log("[flow] (when: predicate false, skipped)"),this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"skipped"});return}try{let l=!!(s.extendedWaitUntil||s.waitFor||s.scrollUntilVisible||s.launchApp||s.runFlow||s.runScript),p=1e4,u=this.runStepInner(s),m;if(l){let g=await u;typeof g=="string"&&(m=g)}else{let g=null,P=new Promise((k,H)=>{g=setTimeout(()=>{H(new Error(`step watchdog: ${n} made no progress in ${p}ms \u2014 bridge or bundle probably hung`))},p)});try{let k=await Promise.race([u,P]);typeof k=="string"&&(m=k)}finally{g&&clearTimeout(g)}}let y=!!(s.assertVisible||s.assertNotVisible||s.extendedWaitUntil||s.waitFor);this.stepDelay>0&&!y&&await f(this.stepDelay),this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"success",screenshotPath:m})}catch(l){if(this.isOptional(s)){console.log(`[flow] (optional, skipped: ${l.message.slice(0,80)})`),this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"skipped",error:l});return}throw this.lastFailedStep={index:t,kind:n,target:s[n]},this.recordFlowTraceStep({stepIndex:t,stepName:n,targetLabel:a,startedAtMs:o,status:"failure",error:l}),l}}async runStepInner(e){if(e.tapOn)await this.tapOn(e.tapOn);else if(e.longPressOn)await this.longPressOn(e.longPressOn);else if(e.scrollUntilVisible)await this.scrollUntilVisible(e.scrollUntilVisible);else if(e.extendedWaitUntil)await this.extendedWaitUntil(e.extendedWaitUntil);else if(e.assertVisible)await this.assertVisible(e.assertVisible);else if(e.assertNotVisible)await this.assertNotVisible(e.assertNotVisible);else if(e.inputText)await this.inputText(e.inputText);else if(e.pressKey)await this.pressKey(e.pressKey);else if(e.dispatchKey)await this.dispatchKey(e.dispatchKey);else if(e.waitFor)await this.waitFor(e.waitFor);else{if(e.takeScreenshot)return this.takeScreenshot(e.takeScreenshot);if(e.swipe)e.swipe.start&&e.swipe.end?await this.swipeCoords(e.swipe.start,e.swipe.end,e.swipe.duration):e.swipe.from?await this.swipeFrom(e.swipe.from,e.swipe.direction,e.swipe.duration):await this.swipe(e.swipe.direction,e.swipe.duration);else if(e.scroll)await this.swipe(e.scroll.direction==="DOWN"?"UP":"DOWN");else if(e.scrollTo){let t=typeof e.scrollTo.nodeId=="number"?{nodeId:e.scrollTo.nodeId}:e.scrollTo.id;if(!t)throw new Error("scrollTo requires id or nodeId");await this.scrollTo(t,e.scrollTo.x,e.scrollTo.y)}else if(e.pinch)await this.pinch(e.pinch);else if(e.waitForAnimationToEnd){let t=e.waitForAnimationToEnd;await this.waitForAnimationToEnd(typeof t=="number"?t:typeof t=="object"&&typeof t.timeout=="number"?t.timeout:2e3)}else if(e.back)await this.back();else if(e.hideKeyboard)await this.hideKeyboard();else if(e.launchApp)await this.launchApp(e.launchApp);else if(typeof e.wait=="number")await f(e.wait);else if(e.dumpTree)await this.dumpTree(e.dumpTree);else if(e.tapAtCoords)await this.tapAtCoords(e.tapAtCoords.x,e.tapAtCoords.y);else if(e.doubleTapAtCoords)await this.doubleTapAtCoords(e.doubleTapAtCoords.x,e.doubleTapAtCoords.y,e.doubleTapAtCoords.gapMs);else if(e.assertTreeContains)await this.assertTreeContains(e.assertTreeContains);else if(typeof e.eraseText=="number")await this.eraseText(e.eraseText);else if(e.repeat&&Array.isArray(e.repeat.commands)){let t=e.repeat.times,r=t==null||t===""?Number.MAX_SAFE_INTEGER:Number(t);if(!Number.isFinite(r))throw new Error(`repeat.times is not a number: ${t}`);let n=e.repeat.when??e.repeat.condition,o=async()=>n?this.evaluateWhen(n):!0,a=n?r:Math.min(r,1e3),s=0;for(;s<a&&await o();){for(let l=0;l<e.repeat.commands.length;l++)await this.runStep(e.repeat.commands[l],l);s++}}else if(e.stopApp!==void 0)await this.stopApp();else if(e.clearState!==void 0)await this.clearState();else if(e.clearKeychain!==void 0)this.clearKeychain();else if(e.copyTextFrom!==void 0)await this.copyTextFrom(e.copyTextFrom);else if(typeof e.evalScript=="string")this.evalScript(e.evalScript);else if(e.runScript){let t=e.runScript,r=typeof t=="string"?void 0:t.when;if(r&&!await this.evaluateWhen(r)){console.log("[flow] runScript skipped (when predicate false)");return}this.runScript(t)}else if(e.openLink!==void 0)await this.openLink(e.openLink);else if(e.runFlow){let t=e.runFlow,r=typeof t=="string"?t:t.file,n=typeof t=="string"?void 0:t.commands,o=typeof t=="string"?void 0:t.env,a=typeof t=="string"?void 0:t.when;if(a&&!await this.evaluateWhen(a)){console.log(`[flow] runFlow skipped (when predicate false): ${r??"inline commands"}`);return}if(!r&&!n)throw new Error("runFlow requires either file or commands");this.js.enterEnvScope();try{if(o)for(let[s,l]of Object.entries(o))this.js.putEnv(s,l);if(r){let s=S.resolve(this.opts.flowDir,r),l=v.readFileSync(s,"utf8"),p=this.opts.flowDir;this.opts.flowDir=S.dirname(s);try{await this.runFlow(Jt(l))}finally{this.opts.flowDir=p}}else if(n)for(let s=0;s<n.length;s++)await this.runStep(n[s],s)}finally{this.js.leaveEnvScope()}}else throw new Error(`unsupported flow step: ${JSON.stringify(e)}`)}}liveStatus=null;async runFlow(e){let t=[],r=[],n=[];for(let a of e){let s=Object.keys(a);if(s.length===1&&s[0]==="onFlowStart"&&Array.isArray(a.onFlowStart)){t.push(...a.onFlowStart);continue}if(s.length===1&&s[0]==="onFlowComplete"&&Array.isArray(a.onFlowComplete)){r.push(...a.onFlowComplete);continue}n.push(a)}if(this.liveStatus&&await this.liveStatus.plan(n.map((a,s)=>{let l=typeof a=="string"?pt(a):a,p=Object.keys(l).find(u=>u!=="when")??Object.keys(l)[0];return{index:s,name:p,target:this.flowStepTargetLabel(l,p)}})),t.length>0){console.log(`[flow] onFlowStart (${t.length} steps)`);for(let a=0;a<t.length;a++)await this.runStep(t[a],a)}let o=null;try{await this.runFlowBody(n)}catch(a){o=a instanceof Error?a:new Error(String(a))}if(r.length>0){console.log(`[flow] onFlowComplete (${r.length} steps)`);for(let a=0;a<r.length;a++)try{await this.runStep(r[a],a)}catch(s){console.warn(`[flow] onFlowComplete step ${a+1} failed: ${s instanceof Error?s.message:s}`)}}if(o)throw o}async runFlowBody(e){for(let t=0;t<e.length;t++){let r=e[t],n=typeof r.wait=="number"?r.wait:0,o=typeof r.waitFor?.timeout=="number"?r.waitFor.timeout:0,a=typeof r.extendedWaitUntil?.timeout=="number"?r.extendedWaitUntil.timeout:0,s=Math.max(6e4,n+15e3,q(o)+15e3,q(a)+15e3);this.liveStatus&&(await this.liveStatus.waitWhilePaused(),await this.liveStatus.step(t,"running"));let l=Date.now(),p=async(u,m)=>{if(!this.liveStatus)return;let y=this.flowTraceSteps[this.flowTraceSteps.length-1],g=y&&y.stepIndex===t&&y.startedAtMs>=l;await this.liveStatus.step(t,u?"failure":g&&y.status==="skipped"?"skipped":"success",{durationMs:Date.now()-l,error:u?m instanceof Error?m.message.slice(0,300):String(m).slice(0,300):g&&y.error||void 0})};try{r.runFlow||r.launchApp?await this.runStep(r,t):await Promise.race([this.runStep(r,t),new Promise((u,m)=>setTimeout(()=>m(new Error(`step ${t+1} (${Object.keys(r)[0]}) exceeded ${s}ms deadline`)),s))])}catch(u){let m=this.flowTraceSteps[this.flowTraceSteps.length-1];if(!(m&&m.stepIndex===t&&m.startedAtMs>=l)){let y=Object.keys(r)[0];this.lastFailedStep={index:t,kind:y,target:r[y]},this.recordFlowTraceStep({stepIndex:t,stepName:y,targetLabel:this.flowStepTargetLabel(r,y),startedAtMs:l,status:"failure",error:u})}throw await p(!0,u),u}await p(!1)}}};function Gt(i){if(typeof i!="object"||i==null||!("control"in i))return!1;let e=i.control;return typeof e=="object"&&e!=null&&"paused"in e&&e.paused===!0}var oe=class{constructor(e,t,r){this.bridge=e;this.flowName=t;this.getSimId=r}disabled=!1;paused=!1;lastSimId;plannedSteps=null;completedSteps=new Map;runId=`flr_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`;async send(e,t){let r=await this.bridge.send({type:"flowStatus",simId:t,status:{runId:this.runId,flowName:this.flowName,...e}});this.paused=Gt(r)}async push(e){if(!this.disabled)try{let t=this.getSimId?.();if(t!==this.lastSimId&&this.lastSimId!=null&&this.plannedSteps&&e.phase!=="plan"){await this.send({phase:"plan",state:"running",steps:this.plannedSteps},t);for(let r of this.completedSteps.values())await this.send({phase:"step",state:"running",step:r},t)}this.lastSimId=t,await this.send(e,t)}catch(t){this.disabled=!0,console.log(`[flow] live status unavailable (${t instanceof Error?t.message.slice(0,120):t}) \u2014 continuing without the devtools rail`)}}async plan(e){this.plannedSteps=e.map(t=>({...t})),this.completedSteps.clear(),await this.push({phase:"plan",state:"running",steps:e})}async step(e,t,r){let n={index:e,status:t,...r};await this.push({phase:"step",state:"running",step:n}),this.completedSteps.set(e,n)}async end(e){await this.push({phase:"end",state:e})}async waitWhilePaused(){if(!this.disabled)for(;this.paused;){for(console.log("[flow] paused from devtools \u2014 waiting\u2026");this.paused&&!this.disabled;)await new Promise(e=>setTimeout(e,400)),await this.push({phase:"heartbeat",state:"paused"});this.disabled||console.log("[flow] resumed")}}};var Ie=null;function Hr(){return Ie}var $e=[];function Wr(){return $e}async function zt(i){if(!i)return"";let e=i.trim();if(!e)return"";if(/^\d+$/.test(e)||e.startsWith("http://")||e.startsWith("https://"))return e;let r=(await We()).find(n=>n.name.toLowerCase()===e.toLowerCase());return r?String(r.preferredPort):e}async function Yt(){let i=await Ue(),e=i.find(r=>r.patched);if(e)return`http://localhost:${e.port}/__soot/`;let t=i[0];return t?`http://localhost:${t.port}/__soot/`:null}async function ft(i){Ie=null,$e=[],(i.length===0||i.includes("--help")||i.includes("-h"))&&(console.log(`
464
464
  sootsim maestro \u2014 author and run Maestro YAML flows
465
465
 
466
466
  usage:
@@ -540,28 +540,28 @@ flow extension:
540
540
  takeScreenshot:
541
541
  path: marketing/hero
542
542
  withFrame: true
543
- `),process.exit(0));let e=i[0];P.existsSync(e)||(console.error(` error: ${e} not found`),process.exit(1));let t=h=>i.find((c,y)=>i[y-1]===h),r=i.includes("--profile"),n=i.includes("--headed"),o=i.includes("--new")||n,a=t("--out")||"/tmp/sootsim-recordings",s=t("--screenshots")||(t("--out")?a:"/tmp/sootsim-flow"),l=t("--screenshot-paths")==="flow"?"flow":"dir",p=i.includes("--no-shell")?"tenant":i.includes("--shell-only")?"shell":void 0,u=t("--device")?.trim()||"",m=i.includes("--slow")?+(t("--slow")||"500"):0,b=i.includes("--electron"),g=i.includes("--preview"),I=await ot(t("--preview-origin")),k=t("--preview-public-origin"),H=i.includes("--preview-open"),Pe=t("--owner")?.trim()||"",ke=t("--repo")?.trim()||"",W=t("--billing-kind")?.trim()||"",mt=g?`maestro:${process.env.GITHUB_RUN_ID?`github:${process.env.GITHUB_RUN_ID}:attempt:${process.env.GITHUB_RUN_ATTEMPT||"1"}:job:${process.env.GITHUB_JOB||"preview"}`:`local:${Kt()}`}:flow:${zt("sha256").update(w.relative(process.cwd(),w.resolve(e))).digest("hex").slice(0,16)}`:"";W&&W!=="test_run"&&(console.error(` error: invalid --billing-kind: ${W}`),process.exit(1));let gt=i.flatMap((h,c)=>i[c-1]==="--replace"?["--replace",h]:[]),wt=i.flatMap((h,c)=>i[c-1]==="--remap"?["--remap",h]:[]),M=i.includes("--record")||g,bt=i.includes("--tail-wait")?Math.max(0,+(t("--tail-wait")||"2000")):M?g?6e3:2e3:0,yt=P.readFileSync(e,"utf8"),{frontmatter:T,steps:R}=we(yt);R.length===0&&(console.error(" error: flow file must contain a YAML array of steps"),process.exit(1));let j=u||T.device||"",Ae=T.theme||"",Z=b||T.electron===!0,St=T.app===void 0||T.app===null?"":typeof T.app=="number"?String(T.app):T.app,se=await qt(St),Me={stripBooleanFlags:["--record","--profile","--electron","--new","--preview","--preview-open","--headless","--headed"],stripValueFlags:["--out","--device","--slow","--tail-wait","--url","--replace","--remap","--screenshots","--screenshot-paths","--preview-origin","--preview-public-origin","--driver","--billing-kind","--owner","--repo"]},x=he(i,Me),vt=t("--url")||"";Z&&!qe()&&(console.error(" error: desktop companion not found. install or build it first with `bun run build:electron`"),process.exit(1));let Re=Z?"desktop companion":"bridge",xt=se?` | target: ${se}`:"";console.log(`
543
+ `),process.exit(0));let e=i[0];$.existsSync(e)||(console.error(` error: ${e} not found`),process.exit(1));let t=h=>i.find((c,b)=>i[b-1]===h),r=i.includes("--profile"),n=i.includes("--headed"),o=i.includes("--new")||n,a=t("--out")||"/tmp/sootsim-recordings",s=t("--screenshots")||(t("--out")?a:"/tmp/sootsim-flow"),l=t("--screenshot-paths")==="flow"?"flow":"dir",p=i.includes("--no-shell")?"tenant":i.includes("--shell-only")?"shell":void 0,u=t("--device")?.trim()||"",m=i.includes("--slow")?+(t("--slow")||"500"):0,y=i.includes("--electron"),g=i.includes("--preview"),P=await ot(t("--preview-origin")),k=t("--preview-public-origin"),H=i.includes("--preview-open"),Pe=t("--owner")?.trim()||"",ke=t("--repo")?.trim()||"",W=t("--billing-kind")?.trim()||"",mt=g?`maestro:${process.env.GITHUB_RUN_ID?`github:${process.env.GITHUB_RUN_ID}:attempt:${process.env.GITHUB_RUN_ATTEMPT||"1"}:job:${process.env.GITHUB_JOB||"preview"}`:`local:${qt()}`}:flow:${Kt("sha256").update(w.relative(process.cwd(),w.resolve(e))).digest("hex").slice(0,16)}`:"";W&&W!=="test_run"&&(console.error(` error: invalid --billing-kind: ${W}`),process.exit(1));let gt=i.flatMap((h,c)=>i[c-1]==="--replace"?["--replace",h]:[]),wt=i.flatMap((h,c)=>i[c-1]==="--remap"?["--remap",h]:[]),M=i.includes("--record")||g,yt=i.includes("--tail-wait")?Math.max(0,+(t("--tail-wait")||"2000")):M?g?6e3:2e3:0,bt=$.readFileSync(e,"utf8"),{frontmatter:T,steps:R}=we(bt);R.length===0&&(console.error(" error: flow file must contain a YAML array of steps"),process.exit(1));let U=u||T.device||"",Ae=T.theme||"",Z=y||T.electron===!0,St=T.app===void 0||T.app===null?"":typeof T.app=="number"?String(T.app):T.app,se=await zt(St),Me={stripBooleanFlags:["--record","--profile","--electron","--new","--preview","--preview-open","--headless","--headed"],stripValueFlags:["--out","--device","--slow","--tail-wait","--url","--replace","--remap","--screenshots","--screenshot-paths","--preview-origin","--preview-public-origin","--driver","--billing-kind","--owner","--repo"]},x=he(i,Me),vt=t("--url")||"";Z&&!ze()&&(console.error(" error: desktop companion not found. install or build it first with `bun run build:electron`"),process.exit(1));let Re=Z?"desktop companion":"bridge",xt=se?` | target: ${se}`:"";console.log(`
544
544
  sootsim maestro \u2014 ${w.basename(e)}
545
545
  ${R.length} steps | ${Re}${xt}${M?" | recording":""}${r?" | profiling":""}${m?` | ${m}ms delay`:""}
546
- `),g&&Be({event:"preview_flow_started",properties:{flowName:w.basename(e),stepCount:R.length,mode:Re,electron:Z,record:M,profile:r,previewOrigin:I}});let A=vt||se||"",ae=o||Z&&x.simIdSource!=="flag",_e=t("--driver")||"",le=!1,ce=new Set,Oe=!1;if(!A&&!ae&&x.simIdSource==="none"){let h=ze(x);try{let c=await h.listSims(),y=c.find(D=>D.isPrimary&&D.readyState==="open"),$=c.find(D=>D.readyState==="open"),J=y??$;J&&(Oe=!0,console.log(` reusing active sim: ${J.id}`))}catch{}finally{h.close()}}if(!A&&!Oe&&(ae||x.simIdSource==="none")){let h=await Yt();h||(console.error(" error: no current sim and no sootsim target found"),await ue(),process.exit(1)),A=h}if(A&&j){let h=new URL(await Ye(A));h.searchParams.set("device",j),A=h.toString()}if(A){let h=[A];if(h.push(...gt),h.push(...wt),ae&&h.push("--new"),h.push("--no-describe"),x.simIdSource==="flag"&&x.simId&&h.push("--sim",x.simId),_e&&(h.push("--driver",_e),le=!0),i.includes("--headless")&&!n&&h.push("--headless"),await Xe(h,{port:x.wsPort,timeoutMs:x.commandTimeoutMs}),le){let c=pe();c&&ce.add(c)}}let B=he(i,Me),X=B.simIdSource==="flag"?B.simId:pe()||B.simId,Tt=B.simIdSource==="flag"?"flag":X?"saved":"none",E=fe(B.wsPort,{commandTimeoutMs:B.commandTimeoutMs,simId:X,simIdSource:Tt}),d,De=async()=>{if(Ae&&await E.send({type:"call",simId:d.simId,path:"SootSim.bridges.settings.set",args:["colorScheme",Ae]}),!j)return!1;let h=await E.send({type:"evaluate",simId:d.simId,code:"window.location.href"});if(typeof h=="string"&&h.length>0){let c=new URL(h);c.searchParams.set("device",j),d.setSimRouteHint(c.toString())}return!!await E.send({type:"call",simId:d.simId,path:"SootSim.bridges.settings.set",args:["deviceModel",j]})};if(d=new ie(E,{screenshotDir:s,flowDir:w.dirname(w.resolve(e)),screenshotPathMode:l,screenshotLayers:p,simId:X,recordingOutputDir:M?a:void 0,recordingFormat:g?"mp4":"webm",billingOriginOverride:g?I:void 0,allowGitHubRecording:g,requireRecordingEntitlement:g,onAfterLaunch:async()=>{await De()&&await d.waitForTree(12e4),g&&await E.send({type:"evaluate",simId:d.simId,code:`(() => {
546
+ `),g&&Be({event:"preview_flow_started",properties:{flowName:w.basename(e),stepCount:R.length,mode:Re,electron:Z,record:M,profile:r,previewOrigin:P}});let A=vt||se||"",ae=o||Z&&x.simIdSource!=="flag",_e=t("--driver")||"",le=!1,ce=new Set,Oe=!1;if(!A&&!ae&&x.simIdSource==="none"){let h=Ke(x);try{let c=await h.listSims(),b=c.find(D=>D.isPrimary&&D.readyState==="open"),I=c.find(D=>D.readyState==="open"),J=b??I;J&&(Oe=!0,console.log(` reusing active sim: ${J.id}`))}catch{}finally{h.close()}}if(!A&&!Oe&&(ae||x.simIdSource==="none")){let h=await Yt();h||(console.error(" error: no current sim and no sootsim target found"),await ue(),process.exit(1)),A=h}if(A&&U){let h=new URL(await Ye(A));h.searchParams.set("device",U),A=h.toString()}if(A){let h=[A];if(h.push(...gt),h.push(...wt),ae&&h.push("--new"),h.push("--no-describe"),x.simIdSource==="flag"&&x.simId&&h.push("--sim",x.simId),_e&&(h.push("--driver",_e),le=!0),i.includes("--headless")&&!n&&h.push("--headless"),await Xe(h,{port:x.wsPort,timeoutMs:x.commandTimeoutMs}),le){let c=pe();c&&ce.add(c)}}let B=he(i,Me),X=B.simIdSource==="flag"?B.simId:pe()||B.simId,Tt=B.simIdSource==="flag"?"flag":X?"saved":"none",E=fe(B.wsPort,{commandTimeoutMs:B.commandTimeoutMs,simId:X,simIdSource:Tt}),d,De=async()=>{if(Ae&&await E.send({type:"call",simId:d.simId,path:"SootSim.bridges.settings.set",args:["colorScheme",Ae]}),!U)return!1;let h=await E.send({type:"evaluate",simId:d.simId,code:"window.location.href"});if(typeof h=="string"&&h.length>0){let c=new URL(h);c.searchParams.set("device",U),d.setSimRouteHint(c.toString())}return!!await E.send({type:"call",simId:d.simId,path:"SootSim.bridges.settings.set",args:["deviceModel",U]})};if(d=new ie(E,{screenshotDir:s,flowDir:w.dirname(w.resolve(e)),screenshotPathMode:l,screenshotLayers:p,simId:X,recordingOutputDir:M?a:void 0,recordingFormat:g?"mp4":"webm",billingOriginOverride:g?P:void 0,allowGitHubRecording:g,requireRecordingEntitlement:g,onAfterLaunch:async()=>{await De()&&await d.waitForTree(12e4),g&&await E.send({type:"evaluate",simId:d.simId,code:`(() => {
547
547
  const r = window.SootSim?.bridges?.eventRecorder ?? window.__sootsimEventRecorder
548
548
  return r?.start?.() ?? false
549
- })()`})}}),m&&(d.stepDelay=m),d.liveStatus=new oe(E,w.basename(e),()=>d.simId),d.js.putEnv("MAESTRO_FILENAME",w.basename(e,w.extname(e))),T.env&&typeof T.env=="object")for(let[h,c]of Object.entries(T.env))d.js.putEnv(h,c);let _=null,F=null,L=null,O=null,U=null,de=null,V=0,Q=!!R[0]?.launchApp;try{Q||await d.waitForTree(12e4),await De()&&!Q&&await d.waitForTree(12e4),g&&!Q&&!process.env.SOOTSIM_PREVIEW_RESET_DONE&&await d.launchApp({clearState:!0}),M&&(Q?d.prepareRecording():await d.startRecording()),r&&await d.startProfile(),g&&(await E.send({type:"evaluate",simId:d.simId,code:`(() => {
549
+ })()`})}}),m&&(d.stepDelay=m),d.liveStatus=new oe(E,w.basename(e),()=>d.simId),d.js.putEnv("MAESTRO_FILENAME",w.basename(e,w.extname(e))),T.env&&typeof T.env=="object")for(let[h,c]of Object.entries(T.env))d.js.putEnv(h,c);let _=null,F=null,L=null,O=null,j=null,de=null,V=0,Q=!!R[0]?.launchApp;try{Q||await d.waitForTree(12e4),await De()&&!Q&&await d.waitForTree(12e4),g&&!Q&&!process.env.SOOTSIM_PREVIEW_RESET_DONE&&await d.launchApp({clearState:!0}),M&&(Q?d.prepareRecording():await d.startRecording()),r&&await d.startProfile(),g&&(await E.send({type:"evaluate",simId:d.simId,code:`(() => {
550
550
  const r = window.SootSim?.bridges?.eventRecorder ?? window.__sootsimEventRecorder
551
551
  return r?.start?.() ?? false
552
- })()`})||console.warn(" warn: eventRecorder.start() returned false \u2014 preview will upload bundle without replay events")),await d.runFlow(R),r&&(_=await d.stopProfile()),await d.waitForRecordingTail({maxMs:bt,smart:g}),M&&(F=await d.stopRecording(),L=d.getLastRecordingDurationMs()),g&&(O=await E.send({type:"evaluate",simId:d.simId,code:`(() => {
552
+ })()`})||console.warn(" warn: eventRecorder.start() returned false \u2014 preview will upload bundle without replay events")),await d.runFlow(R),r&&(_=await d.stopProfile()),await d.waitForRecordingTail({maxMs:yt,smart:g}),M&&(F=await d.stopRecording(),L=d.getLastRecordingDurationMs()),g&&(O=await E.send({type:"evaluate",simId:d.simId,code:`(() => {
553
553
  const r = window.SootSim?.bridges?.eventRecorder ?? window.__sootsimEventRecorder
554
554
  return r?.stop?.() ?? []
555
- })()`}),console.log(` captured ${O.length} replay events`),U=w.join(s,"preview-final.png"),await d.captureScreenshot(U),console.log(` final screenshot: ${U}`));let c=R.filter(y=>y&&typeof y=="object"&&"takeScreenshot"in y).length;console.log(`
555
+ })()`}),console.log(` captured ${O.length} replay events`),j=w.join(s,"preview-final.png"),await d.captureScreenshot(j),console.log(` final screenshot: ${j}`));let c=R.filter(b=>b&&typeof b=="object"&&"takeScreenshot"in b).length;console.log(`
556
556
  + completed (${R.length} steps)`),c>0&&console.log(` screenshots: ${c} \u2192 ${s}`),_&&ht(_),F&&console.log(` video: ${F}`),console.log()}catch(h){if(r&&!_)try{_=await d.stopProfile()}catch{}if(M&&!F)try{F=await d.stopRecording(),L=d.getLastRecordingDurationMs()}catch(c){console.warn(` recording stop failed: ${c?.message||String(c)}`)}if(g&&!O)try{O=await E.send({type:"evaluate",simId:d.simId,code:`(() => {
557
557
  const r = window.SootSim?.bridges?.eventRecorder ?? window.__sootsimEventRecorder
558
558
  return r?.stop?.() ?? []
559
559
  })()`}),console.log(` captured ${O.length} partial replay events`)}catch(c){console.warn(` event recorder stop failed: ${c?.message||String(c)}`)}console.error(`
560
560
  x failed: ${h.message}
561
- `),_&&(console.log(" partial profile:"),ht(_)),F&&console.log(` partial video: ${F}`);try{let c=d.lastFailedStep,y=c?`step-${String(c.index+1).padStart(2,"0")}-${c.kind}`:"unstaged",$=w.join(s,y);await d.captureFailureBundle($,{error:h,stepIndex:c?.index,stepKind:c?.kind,stepTarget:c?.target}),de=$,console.log(` failure bundle: ${$}`),console.log(" (contents: screenshot.png, describe.json, a11y.txt, tree.txt, console.json, error.json)")}catch(c){try{let y=w.join(s,"error.png");await d.captureScreenshot(y),console.log(` error screenshot: ${y}`)}catch{}console.log(` (failure bundle capture failed: ${c instanceof Error?c.message:String(c)})`)}await Ke(E,{errorsCommand:`sootsim get errors 5${d.simId?` --sim ${d.simId}`:""}`,warningsCommand:`sootsim get warnings 5${d.simId?` --sim ${d.simId}`:""}`,requestsCommand:`sootsim get requests 5${d.simId?` --sim ${d.simId}`:""}`}),V=1}if(await d.liveStatus?.end(V===0?"passed":"failed"),g&&(V===0||F||O))try{let h=await Xt(O??[]),c=["--origin",I,"--events",h];k&&c.push("--public-origin",k),F&&c.push("--video",F),U&&c.push("--screenshot",U),F&&L&&Number.isFinite(L)&&(c.push("--video-duration-ms",String(Math.round(L))),c.push("--recorded-duration-ms",String(Math.round(L))));let y=d.getLastRecordingStartedAtMs();y&&Number.isFinite(y)&&c.push("--recording-started-at-ms",String(Math.round(y))),x.wsPort&&c.push("--port",String(x.wsPort)),d.simId&&c.push("--sim",d.simId),H&&c.push("--open"),Pe&&c.push("--owner",Pe),ke&&c.push("--repo",ke),c.push("--run-scope",mt),W&&c.push("--billing-kind",W),console.log(`
562
- preparing preview upload\u2026`);let $=d.getFlowTraceSteps();$.length>0&&c.push("--timeline-events",await Qt($));let J=await er($,y);J&&c.push("--snapshot-manifest",J),de&&c.push("--failure-bundle",de);let D=d.getLastRecordingFrameStats();D&&c.push("--trace-frame-stats",await tr(D));let{runUpload:Et}=await import("./upload-CRCPDN6G.js");Ie=await Et(c,{})}catch(h){console.error(` preview upload failed: ${h?.message||h}`),V=1}return $e=d.getFlowTraceSteps(),E.close(),le?(d.simId&&ce.add(d.simId),await Zt(x.wsPort,x.commandTimeoutMs,[...ce])):d.simId&&d.simId!==X&&He(d.simId),await ue(),V}async function Zt(i,e,t){let r=[...new Set(t.filter(Boolean))];if(r.length===0)return;let n=fe(i,{commandTimeoutMs:e});try{let o=await n.listSims(),a=r.filter(l=>o.some(p=>p.id===l&&p.readyState==="open"));if(a.length===0)return;let s=await Qe(n,i,e,a);await Ze(o,a),s.closed.length>0&&console.log(` closed flow sim(s): ${s.closed.join(", ")}`),s.remaining.length>0&&console.warn(` warn: flow sim(s) still connected after close: ${s.remaining.join(", ")}`)}catch(o){console.warn(` warn: failed to close flow sim(s): ${o instanceof Error?o.message:String(o)}`)}finally{n.close()}}async function Xt(i){let{gzipSync:e}=await import("zlib"),t=i.map(o=>JSON.stringify(o)).join(`
561
+ `),_&&(console.log(" partial profile:"),ht(_)),F&&console.log(` partial video: ${F}`);try{let c=d.lastFailedStep,b=c?`step-${String(c.index+1).padStart(2,"0")}-${c.kind}`:"unstaged",I=w.join(s,b);await d.captureFailureBundle(I,{error:h,stepIndex:c?.index,stepKind:c?.kind,stepTarget:c?.target}),de=I,console.log(` failure bundle: ${I}`),console.log(" (contents: screenshot.png, describe.json, a11y.txt, tree.txt, console.json, error.json)")}catch(c){try{let b=w.join(s,"error.png");await d.captureScreenshot(b),console.log(` error screenshot: ${b}`)}catch{}console.log(` (failure bundle capture failed: ${c instanceof Error?c.message:String(c)})`)}await qe(E,{errorsCommand:`sootsim get errors 5${d.simId?` --sim ${d.simId}`:""}`,warningsCommand:`sootsim get warnings 5${d.simId?` --sim ${d.simId}`:""}`,requestsCommand:`sootsim get requests 5${d.simId?` --sim ${d.simId}`:""}`}),V=1}if(await d.liveStatus?.end(V===0?"passed":"failed"),g&&(V===0||F||O))try{let h=await Xt(O??[]),c=["--origin",P,"--events",h];k&&c.push("--public-origin",k),F&&c.push("--video",F),j&&c.push("--screenshot",j),F&&L&&Number.isFinite(L)&&(c.push("--video-duration-ms",String(Math.round(L))),c.push("--recorded-duration-ms",String(Math.round(L))));let b=d.getLastRecordingStartedAtMs();b&&Number.isFinite(b)&&c.push("--recording-started-at-ms",String(Math.round(b))),x.wsPort&&c.push("--port",String(x.wsPort)),d.simId&&c.push("--sim",d.simId),H&&c.push("--open"),Pe&&c.push("--owner",Pe),ke&&c.push("--repo",ke),c.push("--run-scope",mt),W&&c.push("--billing-kind",W),console.log(`
562
+ preparing preview upload\u2026`);let I=d.getFlowTraceSteps();I.length>0&&c.push("--timeline-events",await Qt(I));let J=await er(I,b);J&&c.push("--snapshot-manifest",J),de&&c.push("--failure-bundle",de);let D=d.getLastRecordingFrameStats();D&&c.push("--trace-frame-stats",await tr(D));let{runUpload:Et}=await import("./upload-D6KRF57A.js");Ie=await Et(c,{})}catch(h){console.error(` preview upload failed: ${h?.message||h}`),V=1}return $e=d.getFlowTraceSteps(),E.close(),le?(d.simId&&ce.add(d.simId),await Zt(x.wsPort,x.commandTimeoutMs,[...ce])):d.simId&&d.simId!==X&&He(d.simId),await ue(),V}async function Zt(i,e,t){let r=[...new Set(t.filter(Boolean))];if(r.length===0)return;let n=fe(i,{commandTimeoutMs:e});try{let o=await n.listSims(),a=r.filter(l=>o.some(p=>p.id===l&&p.readyState==="open"));if(a.length===0)return;let s=await Qe(n,i,e,a);await Ze(o,a),s.closed.length>0&&console.log(` closed flow sim(s): ${s.closed.join(", ")}`),s.remaining.length>0&&console.warn(` warn: flow sim(s) still connected after close: ${s.remaining.join(", ")}`)}catch(o){console.warn(` warn: failed to close flow sim(s): ${o instanceof Error?o.message:String(o)}`)}finally{n.close()}}async function Xt(i){let{gzipSync:e}=await import("zlib"),t=i.map(o=>JSON.stringify(o)).join(`
563
563
  `)+(i.length?`
564
- `:""),r=e(Buffer.from(t,"utf8")),n=w.join(Y(),`sootsim-events-${Date.now()}.jsonl.gz`);return P.writeFileSync(n,r),console.log(` events: ${i.length} written to ${n} (${r.length} bytes gz)`),n}async function Qt(i){let{gzipSync:e}=await import("zlib"),t=i.map((a,s)=>({schemaVersion:1,t:a.endedAtMs,seq:1e6+s,context:"host",kind:"flow-step",id:`flow-step-${a.stepIndex}`,data:{stepIndex:a.stepIndex,stepNumber:a.stepIndex+1,stepName:a.stepName,...a.targetLabel?{targetLabel:a.targetLabel}:{},status:a.status,durationMs:a.durationMs,startedAtMs:a.startedAtMs,endedAtMs:a.endedAtMs,...a.error?{error:a.error}:{}}})),r=t.map(a=>JSON.stringify(a)).join(`
564
+ `:""),r=e(Buffer.from(t,"utf8")),n=w.join(Y(),`sootsim-events-${Date.now()}.jsonl.gz`);return $.writeFileSync(n,r),console.log(` events: ${i.length} written to ${n} (${r.length} bytes gz)`),n}async function Qt(i){let{gzipSync:e}=await import("zlib"),t=i.map((a,s)=>({schemaVersion:1,t:a.endedAtMs,seq:1e6+s,context:"host",kind:"flow-step",id:`flow-step-${a.stepIndex}`,data:{stepIndex:a.stepIndex,stepNumber:a.stepIndex+1,stepName:a.stepName,...a.targetLabel?{targetLabel:a.targetLabel}:{},status:a.status,durationMs:a.durationMs,startedAtMs:a.startedAtMs,endedAtMs:a.endedAtMs,...a.error?{error:a.error}:{}}})),r=t.map(a=>JSON.stringify(a)).join(`
565
565
  `)+`
566
- `,n=e(Buffer.from(r,"utf8")),o=w.join(Y(),`sootsim-flow-steps-${Date.now()}.jsonl.gz`);return P.writeFileSync(o,n),console.log(` flow trace: ${t.length} step events written to ${o} (${n.length} bytes gz)`),o}async function er(i,e){if(!e)return null;let t=i.flatMap(n=>n.screenshotPath?[{id:`flow-step-${n.stepIndex}`,label:n.targetLabel??`Step ${n.stepIndex+1}`,kind:"interaction",t:Math.max(0,n.endedAtMs-e),path:n.screenshotPath}]:[]);if(t.length===0)return null;let r=w.join(Y(),`sootsim-flow-snapshots-${Date.now()}.json`);return P.writeFileSync(r,JSON.stringify(t)),console.log(` flow snapshots: ${t.length} written to ${r}`),r}async function tr(i){let e=w.join(Y(),`sootsim-frame-stats-${Date.now()}.json`);return P.writeFileSync(e,JSON.stringify(i)),console.log(` frame stats: written to ${e}`),e}async function rr(i){let e=i[0],t=r=>i.find((n,o)=>i[o-1]===r);switch(e){case"start":{let{path:r,state:n}=tt();console.log(" flow draft started"),console.log(` session: ${r}`),console.log(` steps: ${n.steps.length}`);return}case"keep":case"good":{let r=Se();if(r.active||(console.error(" no active flow draft \u2014 run `sootsim maestro start` first"),process.exit(1)),!r.kept){console.log(" no pending action to keep");return}console.log(` kept: ${r.candidate.summary}`),console.log(` steps: ${r.stepCount}`);return}case"end":{let r=t("--output")||(i[1]&&!i[1].startsWith("-")?i[1]:void 0),n=i.includes("--validate")||i.includes("--video"),o=i.includes("--video"),a=Se();a.active&&a.kept&&console.log(` auto-kept trailing action: ${a.candidate.summary}`);let s=rt(r||(n?ir():void 0));if(s.active||(console.error(" no active flow draft \u2014 run `sootsim maestro start` first"),process.exit(1)),!s.valid){console.error(" flow draft is not valid:");for(let l of s.issues)console.error(` - ${l}`);console.error(" draft preserved \u2014 keep at least one real interaction or run `sootsim maestro start` to reset"),process.exit(1)}if(n){let l=or(i,s.outputPath),p=await ft(l);if(p!==0){console.error(`
567
- validation failed \u2014 draft preserved so you can keep iterating`),process.exitCode=p;return}ye(),console.log(` flow draft validated (${s.stepCount} step${s.stepCount===1?"":"s"})`),s.outputPath&&console.log(` saved: ${s.outputPath}`),o&&console.log(" video: recorded during validation run");return}if(ye(),console.log(` flow draft ended (${s.stepCount} step${s.stepCount===1?"":"s"})`),s.outputPath){console.log(` saved: ${s.outputPath}`),console.log(` next: sootsim maestro test ${s.outputPath} --record`);return}console.log(""),process.stdout.write(s.yaml);return}case"validate":{let r=i[1];(!r||r.startsWith("-"))&&(console.error(" usage: sootsim maestro validate <path>"),process.exit(1));let n=be(r);if(n.length>0){console.error(` x ${r} failed validation:`);for(let o of n)console.error(` - ${o}`);process.exit(1)}console.log(` + ${r} looks valid`);return}}}function nr(i){return i[0]==="--sim"&&i.length>=2?[...i.slice(2),"--sim",i[1]]:i}async function jr(i){let e=nr(i),t=e[0];if(t==="start"||t==="keep"||t==="good"||t==="end"||t==="validate")return await rr(e),0;let r=await ft(e);return r!==0&&(process.exitCode=r),r}function ht(i){console.log(""),nt(i)}function ir(){return w.join(Y(),`sootsim-flow-draft-${Date.now()}.yaml`)}function or(i,e){if(!e)throw new Error("validated flow draft requires an output path");let t=[e];for(let r=1;r<i.length;r++){let n=i[r];if(!(n==="--validate"||n==="--video")){if(n==="--output"){r+=1;continue}r===1&&!n.startsWith("-")||t.push(n)}}return!t.includes("--record")&&i.includes("--video")&&t.push("--record"),t}export{ct as a,Rt as b,Hr as c,Wr as d,Yt as e,ft as f,nr as g,jr as h};
566
+ `,n=e(Buffer.from(r,"utf8")),o=w.join(Y(),`sootsim-flow-steps-${Date.now()}.jsonl.gz`);return $.writeFileSync(o,n),console.log(` flow trace: ${t.length} step events written to ${o} (${n.length} bytes gz)`),o}async function er(i,e){if(!e)return null;let t=i.flatMap(n=>n.screenshotPath?[{id:`flow-step-${n.stepIndex}`,label:n.targetLabel??`Step ${n.stepIndex+1}`,kind:"interaction",t:Math.max(0,n.endedAtMs-e),path:n.screenshotPath}]:[]);if(t.length===0)return null;let r=w.join(Y(),`sootsim-flow-snapshots-${Date.now()}.json`);return $.writeFileSync(r,JSON.stringify(t)),console.log(` flow snapshots: ${t.length} written to ${r}`),r}async function tr(i){let e=w.join(Y(),`sootsim-frame-stats-${Date.now()}.json`);return $.writeFileSync(e,JSON.stringify(i)),console.log(` frame stats: written to ${e}`),e}async function rr(i){let e=i[0],t=r=>i.find((n,o)=>i[o-1]===r);switch(e){case"start":{let{path:r,state:n}=tt();console.log(" flow draft started"),console.log(` session: ${r}`),console.log(` steps: ${n.steps.length}`);return}case"keep":case"good":{let r=Se();if(r.active||(console.error(" no active flow draft \u2014 run `sootsim maestro start` first"),process.exit(1)),!r.kept){console.log(" no pending action to keep");return}console.log(` kept: ${r.candidate.summary}`),console.log(` steps: ${r.stepCount}`);return}case"end":{let r=t("--output")||(i[1]&&!i[1].startsWith("-")?i[1]:void 0),n=i.includes("--validate")||i.includes("--video"),o=i.includes("--video"),a=Se();a.active&&a.kept&&console.log(` auto-kept trailing action: ${a.candidate.summary}`);let s=rt(r||(n?ir():void 0));if(s.active||(console.error(" no active flow draft \u2014 run `sootsim maestro start` first"),process.exit(1)),!s.valid){console.error(" flow draft is not valid:");for(let l of s.issues)console.error(` - ${l}`);console.error(" draft preserved \u2014 keep at least one real interaction or run `sootsim maestro start` to reset"),process.exit(1)}if(n){let l=or(i,s.outputPath),p=await ft(l);if(p!==0){console.error(`
567
+ validation failed \u2014 draft preserved so you can keep iterating`),process.exitCode=p;return}be(),console.log(` flow draft validated (${s.stepCount} step${s.stepCount===1?"":"s"})`),s.outputPath&&console.log(` saved: ${s.outputPath}`),o&&console.log(" video: recorded during validation run");return}if(be(),console.log(` flow draft ended (${s.stepCount} step${s.stepCount===1?"":"s"})`),s.outputPath){console.log(` saved: ${s.outputPath}`),console.log(` next: sootsim maestro test ${s.outputPath} --record`);return}console.log(""),process.stdout.write(s.yaml);return}case"validate":{let r=i[1];(!r||r.startsWith("-"))&&(console.error(" usage: sootsim maestro validate <path>"),process.exit(1));let n=ye(r);if(n.length>0){console.error(` x ${r} failed validation:`);for(let o of n)console.error(` - ${o}`);process.exit(1)}console.log(` + ${r} looks valid`);return}}}function nr(i){return i[0]==="--sim"&&i.length>=2?[...i.slice(2),"--sim",i[1]]:i}async function Ur(i){let e=nr(i),t=e[0];if(t==="start"||t==="keep"||t==="good"||t==="end"||t==="validate")return await rr(e),0;let r=await ft(e);return r!==0&&(process.exitCode=r),r}function ht(i){console.log(""),nt(i)}function ir(){return w.join(Y(),`sootsim-flow-draft-${Date.now()}.yaml`)}function or(i,e){if(!e)throw new Error("validated flow draft requires an output path");let t=[e];for(let r=1;r<i.length;r++){let n=i[r];if(!(n==="--validate"||n==="--video")){if(n==="--output"){r+=1;continue}r===1&&!n.startsWith("-")||t.push(n)}}return!t.includes("--record")&&i.includes("--video")&&t.push("--record"),t}export{ct as a,Rt as b,Hr as c,Wr as d,Yt as e,ft as f,nr as g,Ur as h};
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.271 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a}from"./chunk-7MWXZLC3.js";import"./chunk-KDQDKEGD.js";export{a as getCliVersion};