sootsim 0.1.212 → 0.1.214

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 (141) hide show
  1. package/README.md +6 -6
  2. package/dist-cli/bin.js +4 -4
  3. package/dist-cli/chunks/{agent-SEHSNZX6.js → agent-QE4ZAHV2.js} +2 -2
  4. package/dist-cli/chunks/{agent-wrapper-YMUSFYO4.js → agent-wrapper-E5HCJNYH.js} +2 -2
  5. package/dist-cli/chunks/{app-fonts-P7IHVY46.js → app-fonts-4ADYMRQO.js} +2 -2
  6. package/dist-cli/chunks/{assert-AZZHFMFN.js → assert-QZSX66RW.js} +2 -2
  7. package/dist-cli/chunks/{auth-QWPDQK3C.js → auth-LW224VBS.js} +2 -2
  8. package/dist-cli/chunks/beta-VXRR4GRU.js +2 -0
  9. package/dist-cli/chunks/{camera-LQTWHUE6.js → camera-MPIQ3JAA.js} +2 -2
  10. package/dist-cli/chunks/{chunk-YNEFNAKF.js → chunk-2344ZBLD.js} +2 -2
  11. package/dist-cli/chunks/{chunk-ATFY2JZZ.js → chunk-2HCVCJB7.js} +3 -3
  12. package/dist-cli/chunks/{chunk-6DPNSUZZ.js → chunk-3CNHHY7U.js} +1 -1
  13. package/dist-cli/chunks/{chunk-FMITPB4T.js → chunk-4RHFQCED.js} +3 -3
  14. package/dist-cli/chunks/{chunk-TUMOXM4E.js → chunk-5LD4QHER.js} +2 -2
  15. package/dist-cli/chunks/{chunk-KRJRWLOW.js → chunk-5P6QAHAI.js} +1 -1
  16. package/dist-cli/chunks/{chunk-WLFIL6JU.js → chunk-6EP67RW7.js} +2 -2
  17. package/dist-cli/chunks/{chunk-7SYXBGM2.js → chunk-6LJUMA3J.js} +2 -2
  18. package/dist-cli/chunks/{chunk-O7K44ZT6.js → chunk-6QMGV5H7.js} +2 -2
  19. package/dist-cli/chunks/{chunk-3L6FBCSH.js → chunk-AXXJSIT3.js} +2 -2
  20. package/dist-cli/chunks/{chunk-KOARSZSJ.js → chunk-AYY7JBXA.js} +1 -1
  21. package/dist-cli/chunks/{chunk-5FQMI3PB.js → chunk-BNUZWRON.js} +1 -1
  22. package/dist-cli/chunks/{chunk-DOCQ4YBT.js → chunk-CZZZC3BU.js} +2 -2
  23. package/dist-cli/chunks/{chunk-7T4AAWY2.js → chunk-DABWOLOT.js} +2 -2
  24. package/dist-cli/chunks/{chunk-FSJQB6FI.js → chunk-DUGNFSB5.js} +2 -2
  25. package/dist-cli/chunks/{chunk-44LPHPGF.js → chunk-FZPRFSTA.js} +1 -1
  26. package/dist-cli/chunks/{chunk-TBLMSWZ6.js → chunk-GTRGDGRK.js} +1 -1
  27. package/dist-cli/chunks/{chunk-ACGAAVPX.js → chunk-I4UH6RI5.js} +2 -2
  28. package/dist-cli/chunks/{chunk-TPD4GIHM.js → chunk-IUTSWOUM.js} +2 -2
  29. package/dist-cli/chunks/{chunk-SC67TYH6.js → chunk-KHIKG5LO.js} +1 -1
  30. package/dist-cli/chunks/{chunk-DWL4WFZ2.js → chunk-KPRSDBWU.js} +1 -1
  31. package/dist-cli/chunks/{chunk-QXDO6QT5.js → chunk-L3CQVAWX.js} +20 -8
  32. package/dist-cli/chunks/{chunk-TKGMBU6V.js → chunk-L5XB3GRM.js} +2 -2
  33. package/dist-cli/chunks/{chunk-WSI6YFMI.js → chunk-LRIZ5ACL.js} +3 -3
  34. package/dist-cli/chunks/chunk-NQDDEWYD.js +1 -0
  35. package/dist-cli/chunks/{chunk-W7RH3GDB.js → chunk-QPZW76ZB.js} +2 -2
  36. package/dist-cli/chunks/{chunk-7BH3S3L3.js → chunk-R35AOOU4.js} +2 -2
  37. package/dist-cli/chunks/{chunk-4RU6YTEP.js → chunk-RRFWPEQ6.js} +1 -1
  38. package/dist-cli/chunks/{chunk-YFXU4HRJ.js → chunk-SLX3HZPR.js} +1 -1
  39. package/dist-cli/chunks/{chunk-AOUNFYEN.js → chunk-T7CWPTU7.js} +2 -2
  40. package/dist-cli/chunks/{chunk-TWNBIOWX.js → chunk-TI2ZOHON.js} +1 -1
  41. package/dist-cli/chunks/chunk-TQ7WAA2M.js +119 -0
  42. package/dist-cli/chunks/{chunk-ERG3QCK4.js → chunk-TX53NA5W.js} +1 -1
  43. package/dist-cli/chunks/{chunk-TWNZ24EL.js → chunk-USSUXBPG.js} +1 -1
  44. package/dist-cli/chunks/{chunk-HTX3YVCJ.js → chunk-USW3U45B.js} +2 -2
  45. package/dist-cli/chunks/{chunk-OHRSRPEB.js → chunk-WEBUMXLD.js} +2 -2
  46. package/dist-cli/chunks/chunk-WF6AY4K4.js +1 -0
  47. package/dist-cli/chunks/{chunk-4IBUPIN6.js → chunk-XJEIT5CH.js} +4 -4
  48. package/dist-cli/chunks/{chunk-SPEEWUAK.js → chunk-XQP4TU6P.js} +4 -4
  49. package/dist-cli/chunks/{chunk-ETXSEPTH.js → chunk-Y3T4POUK.js} +2 -2
  50. package/dist-cli/chunks/{chunk-4AEJLWKA.js → chunk-YVIUYF5U.js} +1 -1
  51. package/dist-cli/chunks/{chunk-QG3N3XNK.js → chunk-Z6X2QRA3.js} +3 -3
  52. package/dist-cli/chunks/cli-version-5DZ5FKJC.js +2 -0
  53. package/dist-cli/chunks/{compat-GLOXSMDS.js → compat-IZXTAA6Q.js} +3 -3
  54. package/dist-cli/chunks/{config-QLSJASDG.js → config-KV7J63HM.js} +2 -2
  55. package/dist-cli/chunks/{control-HW7J3XVA.js → control-CRJA7SXC.js} +2 -2
  56. package/dist-cli/chunks/daemon-LOYTWGGF.js +2 -0
  57. package/dist-cli/chunks/{debug-Q2STL45F.js → debug-ZCPDU23K.js} +3 -3
  58. package/dist-cli/chunks/{desktop-LJJVJIU3.js → desktop-HKTZX7OT.js} +3 -3
  59. package/dist-cli/chunks/{detox-WBTVTSHD.js → detox-LNWHCNFM.js} +2 -2
  60. package/dist-cli/chunks/{device-E3JPFQZM.js → device-AV34WOXK.js} +2 -2
  61. package/dist-cli/chunks/{diagnose-VECVKV6Z.js → diagnose-7INR3HKD.js} +2 -2
  62. package/dist-cli/chunks/drivers-Z2TX4DMF.js +2 -0
  63. package/dist-cli/chunks/flow-7XFQKTBU.js +2 -0
  64. package/dist-cli/chunks/help-ODEIEVZ6.js +2 -0
  65. package/dist-cli/chunks/{home-paths-CRN2V4ZP.js → home-paths-ML5HT67C.js} +2 -2
  66. package/dist-cli/chunks/inspect-KFGNZ2E3.js +2 -0
  67. package/dist-cli/chunks/install-desktop-GTMDR7D5.js +2 -0
  68. package/dist-cli/chunks/{login-FZTKNUQU.js → login-IND3C7NP.js} +4 -4
  69. package/dist-cli/chunks/{logout-FBH74CJM.js → logout-H6R4RQK7.js} +2 -2
  70. package/dist-cli/chunks/{maestro-NRDQGJYE.js → maestro-IVTBNNF6.js} +3 -3
  71. package/dist-cli/chunks/{maestro-generate-RFAXAENX.js → maestro-generate-WCFBU5JM.js} +3 -3
  72. package/dist-cli/chunks/mode-OXPEBMF2.js +111 -0
  73. package/dist-cli/chunks/optional-demo-registry-CHOUOWFF.js +2 -0
  74. package/dist-cli/chunks/{perf-K2IHHZXM.js → perf-TNLPQUZI.js} +2 -2
  75. package/dist-cli/chunks/{record-RE6KIPXY.js → record-MBJMHM23.js} +3 -3
  76. package/dist-cli/chunks/runtime-NCWCN66Y.js +2 -0
  77. package/dist-cli/chunks/{screenshot-command-S47YKHRV.js → screenshot-command-Q5TFWB2R.js} +3 -3
  78. package/dist-cli/chunks/{screenshots-capture-ZTG4V52X.js → screenshots-capture-AW5VYVOF.js} +9 -9
  79. package/dist-cli/chunks/{serve-3AWTKYDJ.js → serve-L5XOVSCM.js} +2 -2
  80. package/dist-cli/chunks/{setup-66M64ZEI.js → setup-TKXVNVBX.js} +3 -3
  81. package/dist-cli/chunks/{skills-2UDI5RNU.js → skills-GFZ5Z46I.js} +2 -2
  82. package/dist-cli/chunks/{storage-XNTIUIYR.js → storage-SW3CLSLM.js} +2 -2
  83. package/dist-cli/chunks/store-5AQQ6HKE.js +2 -0
  84. package/dist-cli/chunks/telemetry-L2M7NRKA.js +2 -0
  85. package/dist-cli/chunks/{timeline-VMPCXPKA.js → timeline-LVV6HPFG.js} +2 -2
  86. package/dist-cli/chunks/{upgrade-UYXVI3XZ.js → upgrade-B22ZDON2.js} +2 -2
  87. package/dist-cli/chunks/upload-UQRYTSL2.js +2 -0
  88. package/dist-cli/chunks/{version-I62N7JTP.js → version-G2X5AZHL.js} +2 -2
  89. package/dist-cli/chunks/web-YCDMLF4V.js +2 -0
  90. package/dist-cli/chunks/{what-happened-3TVVRSN4.js → what-happened-2DEQUI25.js} +2 -2
  91. package/dist-lib/agent-daemon-client.cjs +1 -1
  92. package/dist-lib/agent-events.cjs +1 -1
  93. package/dist-lib/agent-identity.cjs +1 -1
  94. package/dist-lib/agent-sessions.cjs +1 -1
  95. package/dist-lib/attached-projects.cjs +1 -1
  96. package/dist-lib/auth/shared-session.cjs +1 -1
  97. package/dist-lib/backend-origin.cjs +1 -1
  98. package/dist-lib/beta.cjs +1 -1
  99. package/dist-lib/beta.mjs +1 -1
  100. package/dist-lib/bridge-constants.cjs +1 -1
  101. package/dist-lib/cli-constants.cjs +1 -1
  102. package/dist-lib/config.cjs +1 -1
  103. package/dist-lib/detox/index.cjs +1 -1
  104. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  105. package/dist-lib/home-paths.cjs +1 -1
  106. package/dist-lib/host/bridge-host.cjs +1 -1
  107. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  108. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  109. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  110. package/dist-lib/host/websocket-proxy.cjs +1 -1
  111. package/dist-lib/index.cjs +1 -1
  112. package/dist-lib/jump-to-source-babel.cjs +1 -1
  113. package/dist-lib/menu.cjs +1 -1
  114. package/dist-lib/menu.mjs +1 -1
  115. package/dist-lib/metro.cjs +1 -1
  116. package/dist-lib/profiles.cjs +1 -1
  117. package/dist-lib/render-mode.cjs +1 -1
  118. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  119. package/dist-lib/sdk.cjs +11 -3
  120. package/dist-lib/sdk.mjs +11 -3
  121. package/dist-lib/skills.cjs +3 -3
  122. package/dist-lib/vite.cjs +1 -1
  123. package/package.json +1 -1
  124. package/dist-cli/chunks/beta-G6PO4MUG.js +0 -2
  125. package/dist-cli/chunks/chunk-2ZF3OFCV.js +0 -1
  126. package/dist-cli/chunks/chunk-MTIPOS45.js +0 -1
  127. package/dist-cli/chunks/chunk-SX5MJUQC.js +0 -119
  128. package/dist-cli/chunks/cli-version-YGN377WG.js +0 -2
  129. package/dist-cli/chunks/daemon-66EHUQG5.js +0 -2
  130. package/dist-cli/chunks/drivers-SOBHAYVL.js +0 -2
  131. package/dist-cli/chunks/flow-P3QRESKR.js +0 -2
  132. package/dist-cli/chunks/help-NHIRWWJQ.js +0 -2
  133. package/dist-cli/chunks/inspect-DAGGHG65.js +0 -2
  134. package/dist-cli/chunks/install-desktop-HLFM6Q6M.js +0 -2
  135. package/dist-cli/chunks/mode-IXMJSPUT.js +0 -95
  136. package/dist-cli/chunks/optional-demo-registry-ZDULKK6R.js +0 -2
  137. package/dist-cli/chunks/runtime-BFBAWZDT.js +0 -2
  138. package/dist-cli/chunks/store-YOG762Q4.js +0 -2
  139. package/dist-cli/chunks/telemetry-ZANU3YOO.js +0 -2
  140. package/dist-cli/chunks/upload-RNDBU5AE.js +0 -2
  141. package/dist-cli/chunks/web-42YNSI2X.js +0 -2
package/README.md CHANGED
@@ -48,7 +48,7 @@ runtime tarball is rebuilt and re-fetched.
48
48
 
49
49
  The architecture is a **three-tier relay**: a short-lived CLI process, a single
50
50
  persistent bridge daemon, and the sim itself — a browser/Electron *page* that
51
- internally splits into a **shell worker** and a **tenant worker**.
51
+ internally splits into shell, compositor, and tenant workers.
52
52
 
53
53
  ```mermaid
54
54
  graph TD
@@ -74,6 +74,7 @@ graph TD
74
74
  end
75
75
  subgraph sim["sim page (browser / Electron, launched by a driver)"]
76
76
  SHELLW["shell worker (iOS chrome, home grid, app switcher)"]
77
+ COMPOSITORW["compositor worker (app canvases + independent rAF)"]
77
78
  TENANTW["tenant worker (guest RN app tree)"]
78
79
  end
79
80
  subgraph build["build-time plugins (src/)"]
@@ -157,11 +158,10 @@ localhost. The `AgentHost` extension owns one FIFO reader per agent session and
157
158
  fans agent events out to every subscriber.
158
159
 
159
160
  **The sim** is a browser/Electron *page* launched by a CLI driver. Inside that
160
- page run two workers: the **shell worker** renders iOS chrome (home grid, app
161
- switcher) and the **tenant worker** runs the guest RN tree, sending native-UI
162
- requests up to the shell over `NativeUIRequest`. The bridge always addresses the
163
- **shell worker**, never an undifferentiated sim. (Never say "main" unqualified —
164
- distinguish the host page thread, the shell worker, and the tenant worker.)
161
+ page run three workers: the **shell worker** renders iOS chrome and owns native
162
+ state, the **compositor worker** paints both app canvases, and the **tenant
163
+ worker** runs the guest RN tree and sends native-UI requests to the shell. The
164
+ bridge always addresses the **shell worker**, never an undifferentiated sim.
165
165
 
166
166
  **Two distinct plugin families** round it out, and they must not be conflated:
167
167
 
package/dist-cli/bin.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
3
- import{a as w,b as u}from"./chunks/chunk-44LPHPGF.js";import"./chunks/chunk-TWNBIOWX.js";function f(t){let a=t instanceof Error?t.message:String(t);(/^command timed out after \d+s$/.test(a)||a.startsWith("sim disconnected:")||a.startsWith("bridge never reconnected")||a.startsWith("no sim connected with id ")||a.startsWith("could not connect to ws://")||a.startsWith("sootsim bridge daemon is not running")||a.startsWith("sootsim bridge lockfile is fresh")||a.startsWith("sootsim bridge exited before becoming ready")||a.startsWith("background daemon setup is unavailable")||a.startsWith("sootsim bridge did not start within"))&&!process.env.SOOTSIM_VERBOSE&&(process.stderr.write(` ${a}
2
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
3
+ import{a as w,b as u}from"./chunks/chunk-FZPRFSTA.js";import"./chunks/chunk-TI2ZOHON.js";function f(t){let a=t instanceof Error?t.message:String(t);(/^command timed out after \d+s$/.test(a)||a.startsWith("sim disconnected:")||a.startsWith("bridge never reconnected")||a.startsWith("no sim connected with id ")||a.startsWith("could not connect to ws://")||a.startsWith("sootsim bridge daemon is not running")||a.startsWith("sootsim bridge lockfile is fresh")||a.startsWith("sootsim bridge exited before becoming ready")||a.startsWith("background daemon setup is unavailable")||a.startsWith("sootsim bridge did not start within"))&&!process.env.SOOTSIM_VERBOSE&&(process.stderr.write(` ${a}
4
4
  `),process.exit(1)),t instanceof Error&&t.stack?process.stderr.write(`${t.stack}
5
5
  `):process.stderr.write(`${a}
6
6
  `),process.exit(1)}process.on("unhandledRejection",f);process.on("uncaughtException",f);var h=typeof __SOOTSIM_STANDALONE__<"u"&&__SOOTSIM_STANDALONE__,A=new Set(["desktop"]);function k(t){!h||!A.has(t)||(process.stderr.write(` sootsim ${t} isn't available in the standalone binary \u2014
7
7
  it needs vite / electron / playwright from a project's node_modules.
8
8
  run the npm package instead:
9
9
  sootsim ${t}
10
- `),process.exit(1))}var e=u(process.argv);{let{trackCliEvent:t}=await import("./chunks/telemetry-ZANU3YOO.js");t({event:"cli_command_invoked",properties:{command:e.command||(e.version?"version":e.help?"help":"none"),arg_count:e.commandArgs.length,platform:process.platform,arch:process.arch,node_version:process.versions.node}})}if(e.command!=="serve"&&e.command!=="daemon"){let{consumeRuntimeUpgradeNotice:t}=await import("./chunks/home-paths-CRN2V4ZP.js"),a=t();a&&process.stderr.write(` SootSim engine upgraded to v${a.to}`+(a.from?` (from v${a.from})`:"")+` \xB7 what's new: https://sootsim.com/changelog
11
- `)}async function c(t){let{flushCliTelemetry:a}=await import("./chunks/telemetry-ZANU3YOO.js");await a(),process.exit(t)}if(e.version){let{getCliVersion:t}=await import("./chunks/cli-version-YGN377WG.js"),{IS_BETA:a,BETA_LABEL:i}=await import("./chunks/beta-G6PO4MUG.js"),p=a?` \xB7 ${i}`:"";console.log(`sootsim v${t()}${p}`);let{readActiveRuntime:b}=await import("./chunks/home-paths-CRN2V4ZP.js"),l=b();console.log(l?`runtime v${l}`:"runtime not installed"),await c(0)}if(e.help&&!e.command){let{printHelp:t}=await import("./chunks/help-NHIRWWJQ.js");t(),await c(0)}var o=e.globalFlags.port,r=e.verbose,m=e.globalFlags.device,d=e.globalFlags.theme,v=e.globalFlags.driver,_=e.globalFlags.headless===!0,g=e.globalFlags.sim??e.globalFlags.session??e.globalFlags.tab,s=g?["--sim",g,...e.commandArgs]:e.commandArgs;if(m||d){let{settingsStore:t}=await import("./chunks/store-YOG762Q4.js"),a={};m&&(a.deviceModel=m),d&&(a.colorScheme=d),t.apply(a)}if(!e.command&&e.commandArgs.length===0){let{runSetup:t,shouldRunSetupForBareCommand:a}=await import("./chunks/setup-66M64ZEI.js");a()&&(await t(["--from-welcome"]),await c(0));let{printHelp:i}=await import("./chunks/help-NHIRWWJQ.js");i(),await c(0)}var n=e.command??"";if(!n){if(e.commandArgs.length>0){let a=e.commandArgs.find(i=>!i.startsWith("-"))??e.commandArgs[0];console.error(` unknown command: ${a}`),console.error(" run `sootsim --help` to see the full surface."),await c(1)}let{printHelp:t}=await import("./chunks/help-NHIRWWJQ.js");t(),await c(0)}if(e.help||e.commandArgs.includes("--help")||e.commandArgs.includes("-h")){if(n==="skill"){let{runSkill:i}=await import("./chunks/skills-2UDI5RNU.js");await i(e.commandArgs),await c(0)}let t=n==="do"||n==="get"||n==="debug"||n==="shell"||n==="wait",a=e.commandArgs.find(i=>!i.startsWith("-"));if(n!=="shell")if(t&&!a){let{printGroupHelp:i}=await import("./chunks/help-NHIRWWJQ.js");i(n)&&await c(0)}else{let{printCommandHelp:i}=await import("./chunks/help-NHIRWWJQ.js");i(t&&a?a:n,{prefer:t&&a?"verb":"command",group:t&&a?n:void 0}),await c(0)}}k(n);if(w.has(n)){let{runInspect:t}=await import("./chunks/inspect-DAGGHG65.js");await t([n,...s],{port:o,verbose:r})}else switch(n){case"assert":{let{runAssert:t}=await import("./chunks/assert-AZZHFMFN.js");await t(e.commandArgs);break}case"detox":{let{runDetox:t}=await import("./chunks/detox-WBTVTSHD.js");await t(e.commandArgs,{port:o,verbose:r});break}case"maestro":{let{runMaestro:t}=await import("./chunks/maestro-NRDQGJYE.js"),a=await t(s,{port:o,verbose:r});process.exit(typeof a=="number"?a:0)}case"record":{let{runRecord:t}=await import("./chunks/record-RE6KIPXY.js");await t(s,{port:o,verbose:r});break}case"storage":{let{runStorage:t}=await import("./chunks/storage-XNTIUIYR.js"),a=await t(s,{port:o,verbose:r});process.exit(typeof a=="number"?a:0)}case"perf":{let{runPerf:t}=await import("./chunks/perf-K2IHHZXM.js"),a=await t(s,{port:o,verbose:r});process.exit(typeof a=="number"?a:0)}case"screenshot":{let{runScreenshotCommand:t}=await import("./chunks/screenshot-command-S47YKHRV.js"),a=await t(s,{port:o,verbose:r});process.exit(typeof a=="number"?a:0)}case"mode":{let{runMode:t}=await import("./chunks/mode-IXMJSPUT.js");await t(s,{port:o,verbose:r});break}case"inspect":{let{runInspect:t}=await import("./chunks/inspect-DAGGHG65.js");await t(s,{port:o,verbose:r});break}case"debug":{let{runDebug:t}=await import("./chunks/debug-Q2STL45F.js");await t(s,{port:o,verbose:r});break}case"timeline":{let{runTimeline:t}=await import("./chunks/timeline-VMPCXPKA.js");await t(s,{port:o,verbose:r});break}case"what-happened":{let{runWhatHappened:t}=await import("./chunks/what-happened-3TVVRSN4.js");await t(s,{port:o,verbose:r});break}case"open":{let{runOpenCommand:t}=await import("./chunks/control-HW7J3XVA.js");await t(s,{port:o});break}case"use":{let{runUseCommand:t}=await import("./chunks/control-HW7J3XVA.js");await t(s,{port:o});break}case"claim":{let{runClaimCommand:t}=await import("./chunks/control-HW7J3XVA.js");await t(s,{port:o});break}case"close":{let{runCloseCommand:t}=await import("./chunks/control-HW7J3XVA.js");await t(s,{port:o});break}case"device":{let{runDeviceCommand:t}=await import("./chunks/device-E3JPFQZM.js");await t(s,{port:o});break}case"compat":{let{runCompat:t}=await import("./chunks/compat-GLOXSMDS.js");await t(e.commandArgs);break}case"desktop":{let{runDesktop:t}=await import("./chunks/desktop-LJJVJIU3.js");await t(e.commandArgs,{port:o,device:m,driver:v});break}case"login":{let{runLogin:t}=await import("./chunks/login-FZTKNUQU.js");await t(e.commandArgs);break}case"logout":{let{runLogout:t}=await import("./chunks/logout-FBH74CJM.js");await t();break}case"auth":{let{runAuth:t}=await import("./chunks/auth-QWPDQK3C.js");await t(e.commandArgs);break}case"setup":{let{runSetup:t}=await import("./chunks/setup-66M64ZEI.js");await t(e.commandArgs);break}case"serve":{let{runServe:t}=await import("./chunks/serve-3AWTKYDJ.js");await t(e.commandArgs,{port:o});break}case"daemon":{let{runDaemon:t}=await import("./chunks/daemon-66EHUQG5.js");await t(e.commandArgs,{port:o});break}case"runtime":{let{runRuntime:t}=await import("./chunks/runtime-BFBAWZDT.js");await t(e.commandArgs);break}case"upgrade":{let{runUpgrade:t}=await import("./chunks/upgrade-UYXVI3XZ.js");await t(e.commandArgs);break}case"version":{let{runVersion:t}=await import("./chunks/version-I62N7JTP.js");await t(e.commandArgs);break}case"agent":{let{runAgentCommand:t}=await import("./chunks/agent-SEHSNZX6.js"),a=await t(e.commandArgs);process.exit(a)}case"agent-wrapper":{let{runAgentWrapper:t}=await import("./chunks/agent-wrapper-YMUSFYO4.js"),a=await t(e.commandArgs);process.exit(a)}case"skill":{let{runSkill:t}=await import("./chunks/skills-2UDI5RNU.js");await t(e.commandArgs);break}case"app-fonts":{let{runAppFonts:t}=await import("./chunks/app-fonts-P7IHVY46.js");await t(e.commandArgs);break}case"config":{let{runConfig:t}=await import("./chunks/config-QLSJASDG.js");await t(e.commandArgs);break}default:console.error(` unknown command: ${n}`),console.error(" run `sootsim --help` to see the full surface."),process.exit(1)}
10
+ `),process.exit(1))}var e=u(process.argv);{let{trackCliEvent:t}=await import("./chunks/telemetry-L2M7NRKA.js");t({event:"cli_command_invoked",properties:{command:e.command||(e.version?"version":e.help?"help":"none"),arg_count:e.commandArgs.length,platform:process.platform,arch:process.arch,node_version:process.versions.node}})}if(e.command!=="serve"&&e.command!=="daemon"){let{consumeRuntimeUpgradeNotice:t}=await import("./chunks/home-paths-ML5HT67C.js"),a=t();a&&process.stderr.write(` SootSim engine upgraded to v${a.to}`+(a.from?` (from v${a.from})`:"")+` \xB7 what's new: https://sootsim.com/changelog
11
+ `)}async function c(t){let{flushCliTelemetry:a}=await import("./chunks/telemetry-L2M7NRKA.js");await a(),process.exit(t)}if(e.version){let{getCliVersion:t}=await import("./chunks/cli-version-5DZ5FKJC.js"),{IS_BETA:a,BETA_LABEL:i}=await import("./chunks/beta-VXRR4GRU.js"),p=a?` \xB7 ${i}`:"";console.log(`sootsim v${t()}${p}`);let{readActiveRuntime:b}=await import("./chunks/home-paths-ML5HT67C.js"),l=b();console.log(l?`runtime v${l}`:"runtime not installed"),await c(0)}if(e.help&&!e.command){let{printHelp:t}=await import("./chunks/help-ODEIEVZ6.js");t(),await c(0)}var o=e.globalFlags.port,r=e.verbose,m=e.globalFlags.device,d=e.globalFlags.theme,v=e.globalFlags.driver,_=e.globalFlags.headless===!0,g=e.globalFlags.sim??e.globalFlags.session??e.globalFlags.tab,s=g?["--sim",g,...e.commandArgs]:e.commandArgs;if(m||d){let{settingsStore:t}=await import("./chunks/store-5AQQ6HKE.js"),a={};m&&(a.deviceModel=m),d&&(a.colorScheme=d),t.apply(a)}if(!e.command&&e.commandArgs.length===0){let{runSetup:t,shouldRunSetupForBareCommand:a}=await import("./chunks/setup-TKXVNVBX.js");a()&&(await t(["--from-welcome"]),await c(0));let{printHelp:i}=await import("./chunks/help-ODEIEVZ6.js");i(),await c(0)}var n=e.command??"";if(!n){if(e.commandArgs.length>0){let a=e.commandArgs.find(i=>!i.startsWith("-"))??e.commandArgs[0];console.error(` unknown command: ${a}`),console.error(" run `sootsim --help` to see the full surface."),await c(1)}let{printHelp:t}=await import("./chunks/help-ODEIEVZ6.js");t(),await c(0)}if(e.help||e.commandArgs.includes("--help")||e.commandArgs.includes("-h")){if(n==="skill"){let{runSkill:i}=await import("./chunks/skills-GFZ5Z46I.js");await i(e.commandArgs),await c(0)}let t=n==="do"||n==="get"||n==="debug"||n==="shell"||n==="wait",a=e.commandArgs.find(i=>!i.startsWith("-"));if(n!=="shell")if(t&&!a){let{printGroupHelp:i}=await import("./chunks/help-ODEIEVZ6.js");i(n)&&await c(0)}else{let{printCommandHelp:i}=await import("./chunks/help-ODEIEVZ6.js");i(t&&a?a:n,{prefer:t&&a?"verb":"command",group:t&&a?n:void 0}),await c(0)}}k(n);if(w.has(n)){let{runInspect:t}=await import("./chunks/inspect-KFGNZ2E3.js");await t([n,...s],{port:o,verbose:r})}else switch(n){case"assert":{let{runAssert:t}=await import("./chunks/assert-QZSX66RW.js");await t(e.commandArgs);break}case"detox":{let{runDetox:t}=await import("./chunks/detox-LNWHCNFM.js");await t(e.commandArgs,{port:o,verbose:r});break}case"maestro":{let{runMaestro:t}=await import("./chunks/maestro-IVTBNNF6.js"),a=await t(s,{port:o,verbose:r});process.exit(typeof a=="number"?a:0)}case"record":{let{runRecord:t}=await import("./chunks/record-MBJMHM23.js");await t(s,{port:o,verbose:r});break}case"storage":{let{runStorage:t}=await import("./chunks/storage-SW3CLSLM.js"),a=await t(s,{port:o,verbose:r});process.exit(typeof a=="number"?a:0)}case"perf":{let{runPerf:t}=await import("./chunks/perf-TNLPQUZI.js"),a=await t(s,{port:o,verbose:r});process.exit(typeof a=="number"?a:0)}case"screenshot":{let{runScreenshotCommand:t}=await import("./chunks/screenshot-command-Q5TFWB2R.js"),a=await t(s,{port:o,verbose:r});process.exit(typeof a=="number"?a:0)}case"mode":{let{runMode:t}=await import("./chunks/mode-OXPEBMF2.js");await t(s,{port:o,verbose:r});break}case"inspect":{let{runInspect:t}=await import("./chunks/inspect-KFGNZ2E3.js");await t(s,{port:o,verbose:r});break}case"debug":{let{runDebug:t}=await import("./chunks/debug-ZCPDU23K.js");await t(s,{port:o,verbose:r});break}case"timeline":{let{runTimeline:t}=await import("./chunks/timeline-LVV6HPFG.js");await t(s,{port:o,verbose:r});break}case"what-happened":{let{runWhatHappened:t}=await import("./chunks/what-happened-2DEQUI25.js");await t(s,{port:o,verbose:r});break}case"open":{let{runOpenCommand:t}=await import("./chunks/control-CRJA7SXC.js");await t(s,{port:o});break}case"use":{let{runUseCommand:t}=await import("./chunks/control-CRJA7SXC.js");await t(s,{port:o});break}case"claim":{let{runClaimCommand:t}=await import("./chunks/control-CRJA7SXC.js");await t(s,{port:o});break}case"close":{let{runCloseCommand:t}=await import("./chunks/control-CRJA7SXC.js");await t(s,{port:o});break}case"device":{let{runDeviceCommand:t}=await import("./chunks/device-AV34WOXK.js");await t(s,{port:o});break}case"compat":{let{runCompat:t}=await import("./chunks/compat-IZXTAA6Q.js");await t(e.commandArgs);break}case"desktop":{let{runDesktop:t}=await import("./chunks/desktop-HKTZX7OT.js");await t(e.commandArgs,{port:o,device:m,driver:v});break}case"login":{let{runLogin:t}=await import("./chunks/login-IND3C7NP.js");await t(e.commandArgs);break}case"logout":{let{runLogout:t}=await import("./chunks/logout-H6R4RQK7.js");await t();break}case"auth":{let{runAuth:t}=await import("./chunks/auth-LW224VBS.js");await t(e.commandArgs);break}case"setup":{let{runSetup:t}=await import("./chunks/setup-TKXVNVBX.js");await t(e.commandArgs);break}case"serve":{let{runServe:t}=await import("./chunks/serve-L5XOVSCM.js");await t(e.commandArgs,{port:o});break}case"daemon":{let{runDaemon:t}=await import("./chunks/daemon-LOYTWGGF.js");await t(e.commandArgs,{port:o});break}case"runtime":{let{runRuntime:t}=await import("./chunks/runtime-NCWCN66Y.js");await t(e.commandArgs);break}case"upgrade":{let{runUpgrade:t}=await import("./chunks/upgrade-B22ZDON2.js");await t(e.commandArgs);break}case"version":{let{runVersion:t}=await import("./chunks/version-G2X5AZHL.js");await t(e.commandArgs);break}case"agent":{let{runAgentCommand:t}=await import("./chunks/agent-QE4ZAHV2.js"),a=await t(e.commandArgs);process.exit(a)}case"agent-wrapper":{let{runAgentWrapper:t}=await import("./chunks/agent-wrapper-E5HCJNYH.js"),a=await t(e.commandArgs);process.exit(a)}case"skill":{let{runSkill:t}=await import("./chunks/skills-GFZ5Z46I.js");await t(e.commandArgs);break}case"app-fonts":{let{runAppFonts:t}=await import("./chunks/app-fonts-4ADYMRQO.js");await t(e.commandArgs);break}case"config":{let{runConfig:t}=await import("./chunks/config-KV7J63HM.js");await t(e.commandArgs);break}default:console.error(` unknown command: ${n}`),console.error(" run `sootsim --help` to see the full surface."),process.exit(1)}
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as b,b as E,c as A,d as l,e as S,g as j,h as T,j as I,m as k,n as D,o as x,p as g,q as O,r as C}from"./chunk-7T4AAWY2.js";import"./chunk-4AEJLWKA.js";import{c as $}from"./chunk-WLFIL6JU.js";import"./chunk-FSJQB6FI.js";import"./chunk-SX5MJUQC.js";import"./chunk-7BH3S3L3.js";import"./chunk-5FQMI3PB.js";import"./chunk-DWL4WFZ2.js";import{j as y}from"./chunk-ERG3QCK4.js";import"./chunk-YFXU4HRJ.js";import"./chunk-SC67TYH6.js";import"./chunk-AOUNFYEN.js";import"./chunk-TWNBIOWX.js";import w from"node:fs";import d from"node:path";import{spawn as _}from"node:child_process";import F from"node:net";import{WebSocket as R}from"ws";var c=class extends Error{code;constructor(e,t){super(e),this.name="AgentDaemonError",this.code=t}},f=class{ws;port;commandTimeoutMs;ready;closed=!1;nextId=1;pending=new Map;eventListeners=new Set;statusListeners=new Set;disconnectListeners=new Set;constructor(e={}){this.port=e.port??7668,this.commandTimeoutMs=e.commandTimeoutMs??15e3,this.ws=new R(`ws://localhost:${this.port}`),this.ready=new Promise((t,r)=>{let s=()=>{this.ws.off("error",o),t()},o=i=>{this.ws.off("open",s),r(new c(`could not connect to sootsim daemon on port ${this.port}: ${i.message}`,"NO_DAEMON"))};this.ws.once("open",s),this.ws.once("error",o)}),this.ws.on("message",t=>this.handleMessage(t)),this.ws.on("close",()=>this.handleClose()),this.ws.on("error",()=>{})}async waitReady(){return this.ready}async listProjects(){return this.send("agent:list-projects")}async upsertProject(e){return this.send("agent:upsert-project",{input:e})}async deleteProject(e){return this.send("agent:delete-project",{projectId:e})}async autoAttachForUrl(e){return this.send("agent:auto-attach-for-url",{input:e})}async listSessions(e){return this.send("agent:list-sessions",{projectId:e})}async startSession(e){return this.send("agent:start-session",{input:e})}async sendPrompt(e,t){return this.send("agent:send-prompt",{sessionId:e,prompt:t})}async sendClaimedPrompt(e,t){return this.send("agent:send-claimed-prompt",{simId:e,prompt:t})}async endSession(e){return this.send("agent:end-session",{sessionId:e})}async getTranscript(e){return this.send("agent:get-transcript",{sessionId:e})}async getPaths(){return this.send("agent:get-paths")}async subscribeEvents(e){return this.send("agent:subscribe-events",{sessionId:e})}async unsubscribeEvents(e){return this.send("agent:unsubscribe-events",{sessionId:e})}onAgentEvent(e){return this.eventListeners.add(e),()=>this.eventListeners.delete(e)}onSessionStatusChange(e){return this.statusListeners.add(e),()=>this.statusListeners.delete(e)}onDisconnect(e){return this.disconnectListeners.add(e),()=>this.disconnectListeners.delete(e)}close(){if(!this.closed){this.closed=!0;try{this.ws.close()}catch{}}}async send(e,t={}){if(await this.ready,this.closed||this.ws.readyState!==R.OPEN)throw new c("daemon connection is closed","NO_DAEMON");let r=this.nextId++;return new Promise((s,o)=>{let i=setTimeout(()=>{this.pending.delete(r),o(new c(`${e} timed out after ${Math.round(this.commandTimeoutMs/1e3)}s`,"TIMEOUT"))},this.commandTimeoutMs);this.pending.set(r,{resolve:s,reject:o,timer:i});try{this.ws.send(JSON.stringify({id:r,type:e,...t}))}catch(a){clearTimeout(i),this.pending.delete(r),o(a instanceof Error?a:new Error(String(a)))}})}handleMessage(e){let t;try{t=JSON.parse(String(e))}catch{return}if(!t||typeof t!="object")return;if(t.type==="agent:event"){for(let s of this.eventListeners)try{s({sessionId:t.sessionId,event:t.event})}catch{}return}if(t.type==="agent:session-status"){for(let s of this.statusListeners)try{s(t.session)}catch{}return}if(typeof t.id!="number")return;let r=this.pending.get(t.id);r&&(this.pending.delete(t.id),clearTimeout(r.timer),t.error?r.reject(new c(t.error,t.code)):r.resolve(t.result))}handleClose(){if(!this.closed){this.closed=!0;for(let[,e]of this.pending)clearTimeout(e.timer),e.reject(new c("daemon disconnected","DISCONNECT"));this.pending.clear();for(let e of this.disconnectListeners)try{e()}catch{}}}};function M(n=7668,e=400){return new Promise(t=>{let r=new F.Socket,s=!1,o=i=>{s||(s=!0,r.destroy(),t(i))};r.setTimeout(e),r.once("connect",()=>o(!0)),r.once("timeout",()=>o(!1)),r.once("error",()=>o(!1)),r.connect(n,"127.0.0.1")})}async function B(n={}){let e=n.port??7668;if(await M(e))return{alreadyRunning:!0};if(y())throw new c(`no sootsim bridge on port ${e}. run \`sootsim setup\` to install the background daemon, or \`sootsim serve\` in another shell.`,"DEV_HOST_REFUSED");let{cmd:t,prefixArgs:r}=C(),s=[...r,"serve","--quiet"];e!==7668&&s.push("--port",String(e));let o=_(t,s,{detached:!0,stdio:"ignore",env:process.env,cwd:process.cwd()});o.unref();let i=Date.now()+(n.startupTimeoutMs??5e3);for(;Date.now()<i;){if(await M(e))return{alreadyRunning:!1,pid:o.pid};await new Promise(a=>setTimeout(a,100))}throw new c(`spawned sootsim daemon on port ${e} but it did not come up in time. run \`sootsim serve\` manually to diagnose.`,"SPAWN_TIMEOUT")}async function h(n={}){await B({port:n.port,startupTimeoutMs:n.startupTimeoutMs});let e=new f(n);try{await e.waitReady()}catch(t){throw e.close(),t}return e}async function ge(n){let[e,...t]=n;try{switch(e){case void 0:case"--help":case"-h":case"help":return L(),0;case"attach":return await W(t);case"projects":return await J();case"project":return await V(t);case"sessions":return await H(t);case"start":return await G(t);case"prompt":return await q(t);case"watch":return await K(t);case"transcript":return await z(t);case"end":return await Q(t);case"paths":return await Y();default:return process.stderr.write(`unknown agent subcommand: ${e}
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as b,b as E,c as A,d as l,e as S,g as j,h as T,j as I,m as k,n as D,o as x,p as g,q as O,r as C}from"./chunk-DABWOLOT.js";import"./chunk-YVIUYF5U.js";import{c as $}from"./chunk-6EP67RW7.js";import"./chunk-DUGNFSB5.js";import"./chunk-TQ7WAA2M.js";import"./chunk-R35AOOU4.js";import"./chunk-BNUZWRON.js";import"./chunk-KPRSDBWU.js";import{j as y}from"./chunk-TX53NA5W.js";import"./chunk-SLX3HZPR.js";import"./chunk-KHIKG5LO.js";import"./chunk-T7CWPTU7.js";import"./chunk-TI2ZOHON.js";import w from"node:fs";import d from"node:path";import{spawn as _}from"node:child_process";import F from"node:net";import{WebSocket as R}from"ws";var c=class extends Error{code;constructor(e,t){super(e),this.name="AgentDaemonError",this.code=t}},f=class{ws;port;commandTimeoutMs;ready;closed=!1;nextId=1;pending=new Map;eventListeners=new Set;statusListeners=new Set;disconnectListeners=new Set;constructor(e={}){this.port=e.port??7668,this.commandTimeoutMs=e.commandTimeoutMs??15e3,this.ws=new R(`ws://localhost:${this.port}`),this.ready=new Promise((t,r)=>{let s=()=>{this.ws.off("error",o),t()},o=i=>{this.ws.off("open",s),r(new c(`could not connect to sootsim daemon on port ${this.port}: ${i.message}`,"NO_DAEMON"))};this.ws.once("open",s),this.ws.once("error",o)}),this.ws.on("message",t=>this.handleMessage(t)),this.ws.on("close",()=>this.handleClose()),this.ws.on("error",()=>{})}async waitReady(){return this.ready}async listProjects(){return this.send("agent:list-projects")}async upsertProject(e){return this.send("agent:upsert-project",{input:e})}async deleteProject(e){return this.send("agent:delete-project",{projectId:e})}async autoAttachForUrl(e){return this.send("agent:auto-attach-for-url",{input:e})}async listSessions(e){return this.send("agent:list-sessions",{projectId:e})}async startSession(e){return this.send("agent:start-session",{input:e})}async sendPrompt(e,t){return this.send("agent:send-prompt",{sessionId:e,prompt:t})}async sendClaimedPrompt(e,t){return this.send("agent:send-claimed-prompt",{simId:e,prompt:t})}async endSession(e){return this.send("agent:end-session",{sessionId:e})}async getTranscript(e){return this.send("agent:get-transcript",{sessionId:e})}async getPaths(){return this.send("agent:get-paths")}async subscribeEvents(e){return this.send("agent:subscribe-events",{sessionId:e})}async unsubscribeEvents(e){return this.send("agent:unsubscribe-events",{sessionId:e})}onAgentEvent(e){return this.eventListeners.add(e),()=>this.eventListeners.delete(e)}onSessionStatusChange(e){return this.statusListeners.add(e),()=>this.statusListeners.delete(e)}onDisconnect(e){return this.disconnectListeners.add(e),()=>this.disconnectListeners.delete(e)}close(){if(!this.closed){this.closed=!0;try{this.ws.close()}catch{}}}async send(e,t={}){if(await this.ready,this.closed||this.ws.readyState!==R.OPEN)throw new c("daemon connection is closed","NO_DAEMON");let r=this.nextId++;return new Promise((s,o)=>{let i=setTimeout(()=>{this.pending.delete(r),o(new c(`${e} timed out after ${Math.round(this.commandTimeoutMs/1e3)}s`,"TIMEOUT"))},this.commandTimeoutMs);this.pending.set(r,{resolve:s,reject:o,timer:i});try{this.ws.send(JSON.stringify({id:r,type:e,...t}))}catch(a){clearTimeout(i),this.pending.delete(r),o(a instanceof Error?a:new Error(String(a)))}})}handleMessage(e){let t;try{t=JSON.parse(String(e))}catch{return}if(!t||typeof t!="object")return;if(t.type==="agent:event"){for(let s of this.eventListeners)try{s({sessionId:t.sessionId,event:t.event})}catch{}return}if(t.type==="agent:session-status"){for(let s of this.statusListeners)try{s(t.session)}catch{}return}if(typeof t.id!="number")return;let r=this.pending.get(t.id);r&&(this.pending.delete(t.id),clearTimeout(r.timer),t.error?r.reject(new c(t.error,t.code)):r.resolve(t.result))}handleClose(){if(!this.closed){this.closed=!0;for(let[,e]of this.pending)clearTimeout(e.timer),e.reject(new c("daemon disconnected","DISCONNECT"));this.pending.clear();for(let e of this.disconnectListeners)try{e()}catch{}}}};function M(n=7668,e=400){return new Promise(t=>{let r=new F.Socket,s=!1,o=i=>{s||(s=!0,r.destroy(),t(i))};r.setTimeout(e),r.once("connect",()=>o(!0)),r.once("timeout",()=>o(!1)),r.once("error",()=>o(!1)),r.connect(n,"127.0.0.1")})}async function B(n={}){let e=n.port??7668;if(await M(e))return{alreadyRunning:!0};if(y())throw new c(`no sootsim bridge on port ${e}. run \`sootsim setup\` to install the background daemon, or \`sootsim serve\` in another shell.`,"DEV_HOST_REFUSED");let{cmd:t,prefixArgs:r}=C(),s=[...r,"serve","--quiet"];e!==7668&&s.push("--port",String(e));let o=_(t,s,{detached:!0,stdio:"ignore",env:process.env,cwd:process.cwd()});o.unref();let i=Date.now()+(n.startupTimeoutMs??5e3);for(;Date.now()<i;){if(await M(e))return{alreadyRunning:!1,pid:o.pid};await new Promise(a=>setTimeout(a,100))}throw new c(`spawned sootsim daemon on port ${e} but it did not come up in time. run \`sootsim serve\` manually to diagnose.`,"SPAWN_TIMEOUT")}async function h(n={}){await B({port:n.port,startupTimeoutMs:n.startupTimeoutMs});let e=new f(n);try{await e.waitReady()}catch(t){throw e.close(),t}return e}async function ge(n){let[e,...t]=n;try{switch(e){case void 0:case"--help":case"-h":case"help":return L(),0;case"attach":return await W(t);case"projects":return await J();case"project":return await V(t);case"sessions":return await H(t);case"start":return await G(t);case"prompt":return await q(t);case"watch":return await K(t);case"transcript":return await z(t);case"end":return await Q(t);case"paths":return await Y();default:return process.stderr.write(`unknown agent subcommand: ${e}
3
3
  `),L(),2}}catch(r){if(r instanceof c)return process.stderr.write(`${r.message}
4
4
  `),1;throw r}}async function v(n){let e=await h({clientLabel:"sootsim-agent-cli"});try{return await n(e)}finally{e.close()}}function L(){$("agent")}function P(n,e){let t={},r=[];for(let s=0;s<n.length;s++){let o=n[s],i=e[o];i==="value"?(t[o]=n[s+1]??"",s++):i==="bool"?t[o]=!0:r.push(o)}return{flags:t,positional:r}}function U(n,e="codex"){return n==="codex"||n==="claude"?n:e}async function W(n){let{flags:e,positional:t}=P(n,{"--name":"value","--provider":"value"}),r=t[0];if(!r)return process.stderr.write(`usage: sootsim agent attach <dir> [--name X] [--provider codex|claude]
5
5
  `),2;let s=d.resolve(r);if(!w.existsSync(s))return process.stderr.write(`directory does not exist: ${s}
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{b as M}from"./chunk-4AEJLWKA.js";import"./chunk-TWNBIOWX.js";import{execFile as G,spawn as q}from"node:child_process";import{randomUUID as X}from"node:crypto";import{constants as R,createReadStream as Y,createWriteStream as j,existsSync as I,openSync as J}from"node:fs";import V from"node:fs/promises";import z from"node:path";import K from"node:readline";import{promisify as Q}from"node:util";import{spawn as H}from"node:child_process";import L from"node:readline";var b=class extends Error{code;data;constructor(t,r,m){super(t),this.name="CodexRpcError",this.code=r,this.data=m}};function W(d){let t=H(d.bin,["app-server"],{cwd:d.cwd,env:{...process.env,...d.env},stdio:["pipe","pipe","pipe"]}),r=new Map,m=new Map,u=1,g=!1,a=new Promise(s=>{t.on("exit",(i,e)=>{g=!0;let p=new Error(`codex app-server exited (code=${i}, signal=${e??""})`);for(let{reject:f}of r.values())f(p);r.clear(),s({code:i,signal:e})})});L.createInterface({input:t.stdout,crlfDelay:1/0}).on("line",s=>{let i=s.trim();if(!i)return;let e;try{e=JSON.parse(i)}catch{return}if(e.id!=null&&(e.result!==void 0||e.error!==void 0)){let p=typeof e.id=="string"?Number(e.id):e.id,f=p!=null?r.get(p):void 0;if(!f)return;r.delete(p),e.error?f.reject(new b(e.error.message,e.error.code,e.error.data)):f.resolve(e.result);return}if(e.method){let p=m.get(e.method);if(!p)return;for(let f of p)try{f(e.params)}catch(l){console.error(`[codex-client] handler for "${e.method}" threw:`,l instanceof Error?l.stack??l.message:l)}}}),t.stderr.setEncoding("utf8"),t.stderr.on("data",s=>{let i=m.get("__stderr__");if(i)for(let e of i)try{e({text:s})}catch{}});function n(s){if(!g)try{t.stdin.write(JSON.stringify(s)+`
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{b as M}from"./chunk-YVIUYF5U.js";import"./chunk-TI2ZOHON.js";import{execFile as G,spawn as q}from"node:child_process";import{randomUUID as X}from"node:crypto";import{constants as R,createReadStream as Y,createWriteStream as j,existsSync as I,openSync as J}from"node:fs";import V from"node:fs/promises";import z from"node:path";import K from"node:readline";import{promisify as Q}from"node:util";import{spawn as H}from"node:child_process";import L from"node:readline";var b=class extends Error{code;data;constructor(t,r,m){super(t),this.name="CodexRpcError",this.code=r,this.data=m}};function W(d){let t=H(d.bin,["app-server"],{cwd:d.cwd,env:{...process.env,...d.env},stdio:["pipe","pipe","pipe"]}),r=new Map,m=new Map,u=1,g=!1,a=new Promise(s=>{t.on("exit",(i,e)=>{g=!0;let p=new Error(`codex app-server exited (code=${i}, signal=${e??""})`);for(let{reject:f}of r.values())f(p);r.clear(),s({code:i,signal:e})})});L.createInterface({input:t.stdout,crlfDelay:1/0}).on("line",s=>{let i=s.trim();if(!i)return;let e;try{e=JSON.parse(i)}catch{return}if(e.id!=null&&(e.result!==void 0||e.error!==void 0)){let p=typeof e.id=="string"?Number(e.id):e.id,f=p!=null?r.get(p):void 0;if(!f)return;r.delete(p),e.error?f.reject(new b(e.error.message,e.error.code,e.error.data)):f.resolve(e.result);return}if(e.method){let p=m.get(e.method);if(!p)return;for(let f of p)try{f(e.params)}catch(l){console.error(`[codex-client] handler for "${e.method}" threw:`,l instanceof Error?l.stack??l.message:l)}}}),t.stderr.setEncoding("utf8"),t.stderr.on("data",s=>{let i=m.get("__stderr__");if(i)for(let e of i)try{e({text:s})}catch{}});function n(s){if(!g)try{t.stdin.write(JSON.stringify(s)+`
3
3
  `)}catch{}}return{exited:a,on(s,i){let e=m.get(s);return e||(e=new Set,m.set(s,e)),e.add(i),()=>{e?.delete(i)}},request(s,i){if(g)return Promise.reject(new Error(`codex app-server closed; cannot call ${s}`));let e=u++;return new Promise((p,f)=>{r.set(e,{resolve:l=>p(l),reject:f,method:s}),n({jsonrpc:"2.0",id:e,method:s,params:i})})},notify(s,i){n({jsonrpc:"2.0",method:s,params:i})},async shutdown(s=1500){if(g)return;try{t.stdin.end()}catch{}let i=setTimeout(()=>{if(!g)try{t.kill("SIGTERM")}catch{}},s);try{await a}finally{clearTimeout(i)}},kill(s="SIGTERM"){if(!g)try{t.kill(s)}catch{}}}}var O="never",F="danger-full-access",Z={type:"dangerFullAccess"},D="fast",ee="medium",te=Q(G);async function ne(d,t){let r=t||d;if(r.includes("/")||r.includes("\\"))return I(r)?{ok:!0,path:r}:{ok:!1,message:`agent binary not found at path: ${r}`};try{let{stdout:m}=await te("which",[r],{timeout:1500}),u=m.trim();return u?{ok:!0,path:u}:{ok:!1,message:`${r} not found on PATH`}}catch{return{ok:!1,message:`${r} not found on PATH. install the ${d} CLI and retry, or pass --${d}-bin /path/to/${d} to agent start.`}}}function re(d){let t={"--session-id":"sessionId","--project-id":"projectId","--provider":"provider","--cwd":"cwd","--prompt-in":"promptIn","--events-out":"eventsOut","--transcript":"transcript","--codex-bin":"codexBin","--claude-bin":"claudeBin","--claude-session-uuid":"claudeSessionUuid"},r={};for(let m=0;m<d.length;m++){let u=d[m];if(u==="--fresh-thread"){r.freshThread=!0;continue}let g=t[u];g&&(r[g]=d[m+1],m++)}return r}async function Ie(d){let t=re(d);if(!t.sessionId||!t.projectId||!t.provider||!t.cwd||!t.promptIn||!t.eventsOut)return process.stderr.write(`usage: sootsim agent-wrapper --session-id <id> --project-id <id>
4
4
  --provider codex|claude --cwd <path>
5
5
  --prompt-in <fifo> --events-out <fifo>
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{d as p}from"./chunk-KRJRWLOW.js";import"./chunk-TWNBIOWX.js";import{existsSync as h,mkdirSync as d,readFileSync as y,writeFileSync as g}from"node:fs";import{join as m}from"node:path";import{gzipSync as w}from"node:zlib";function f(t,e){let o=t.indexOf(`--${e}`);if(o!==-1&&o+1<t.length)return t[o+1];let i=t.find(r=>r.startsWith(`--${e}=`));return i?i.slice(e.length+3):void 0}async function S(t){let e=f(t,"wire")||"",o=f(t,"out-dir"),i=f(t,"manifest");if((!o||!i)&&(console.error(" usage: sootsim app-fonts stage --wire <wire> --out-dir <dir> --manifest <path>"),process.exit(1)),!e.trim()){console.log("no app fonts declared \u2014 nothing to stage");return}d(o,{recursive:!0});let r=await p(e,{onStaged:({url:n,byteLength:s})=>console.log(` staged app font: ${n} (${(s/1024).toFixed(1)} KiB)`),onError:(n,s)=>console.error(` warning: failed to fetch app font ${n}: ${s instanceof Error?s.message:s}`)}),a=[];for(let n of r){let s=w(n.bytes);g(m(o,n.urlhash),s),a.push({url:n.url,urlhash:n.urlhash,contentType:n.contentType,encoding:"gzip",sizeBytes:s.length,rawBytes:n.bytes.byteLength})}let c=[];if(h(i))try{let n=JSON.parse(y(i,"utf8"));Array.isArray(n)&&(c=n)}catch{}let u=new Set(c.map(n=>n.urlhash)),l=[...c,...a.filter(n=>!u.has(n.urlhash))];g(i,JSON.stringify(l)),console.log(`staged ${a.length} app font(s); manifest now has ${l.length} file(s)`)}async function E(t){let e=t[0];if(e==="stage"){await S(t.slice(1));return}console.error(` unknown app-fonts subcommand: ${e??"(none)"}`),console.error(" available: stage"),process.exit(1)}export{E as runAppFonts};
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{d as p}from"./chunk-5P6QAHAI.js";import"./chunk-TI2ZOHON.js";import{existsSync as h,mkdirSync as d,readFileSync as y,writeFileSync as g}from"node:fs";import{join as m}from"node:path";import{gzipSync as w}from"node:zlib";function f(t,e){let o=t.indexOf(`--${e}`);if(o!==-1&&o+1<t.length)return t[o+1];let i=t.find(r=>r.startsWith(`--${e}=`));return i?i.slice(e.length+3):void 0}async function S(t){let e=f(t,"wire")||"",o=f(t,"out-dir"),i=f(t,"manifest");if((!o||!i)&&(console.error(" usage: sootsim app-fonts stage --wire <wire> --out-dir <dir> --manifest <path>"),process.exit(1)),!e.trim()){console.log("no app fonts declared \u2014 nothing to stage");return}d(o,{recursive:!0});let r=await p(e,{onStaged:({url:n,byteLength:s})=>console.log(` staged app font: ${n} (${(s/1024).toFixed(1)} KiB)`),onError:(n,s)=>console.error(` warning: failed to fetch app font ${n}: ${s instanceof Error?s.message:s}`)}),a=[];for(let n of r){let s=w(n.bytes);g(m(o,n.urlhash),s),a.push({url:n.url,urlhash:n.urlhash,contentType:n.contentType,encoding:"gzip",sizeBytes:s.length,rawBytes:n.bytes.byteLength})}let c=[];if(h(i))try{let n=JSON.parse(y(i,"utf8"));Array.isArray(n)&&(c=n)}catch{}let u=new Set(c.map(n=>n.urlhash)),l=[...c,...a.filter(n=>!u.has(n.urlhash))];g(i,JSON.stringify(l)),console.log(`staged ${a.length} app font(s); manifest now has ${l.length} file(s)`)}async function E(t){let e=t[0];if(e==="stage"){await S(t.slice(1));return}console.error(` unknown app-fonts subcommand: ${e??"(none)"}`),console.error(" available: stage"),process.exit(1)}export{E as runAppFonts};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import"./chunk-TWNBIOWX.js";import{spawn as x}from"child_process";var w=new Set(["describe","find","list","network","logs","count","tree","url","a11y","node","layout","keyboard","errors","warnings","requests","animations","animation","state","sample-color"]),S=new Set(["--exists","--empty","--negate","--quiet","--allow-timeout","!"]),q=new Set(["--count","--count-at-least","--count-at-most","--contains","--not-contains","--matches","--not-matches","--equals","--jq","--has-path","--within"]),P=new Set(["--path-equals"]);function j(s){let r=[],u=[],n=0,e=!1,t=!1,i=!1;for(let o=0;o<s.length;o++){let a=s[o];if(a==="--within"){let c=Number(s[o+1]);if(!Number.isFinite(c)||c<0)return{error:`--within requires a non-negative number, got: ${s[o+1]}`};n=c,o++;continue}if(a==="--negate"||a==="!"){e=!0;continue}if(a==="--quiet"){t=!0;continue}if(a==="--allow-timeout"){i=!0;continue}if(S.has(a)){u.push({kind:a,args:[]});continue}if(q.has(a)){let c=s[o+1];if(c==null)return{error:`${a} requires a value`};u.push({kind:a,args:[c]}),o++;continue}if(P.has(a)){let c=s[o+1],f=s[o+2];if(c==null||f==null)return{error:`${a} requires <path> <value>`};u.push({kind:a,args:[c,f]}),o+=2;continue}r.push(a)}return r.length===0?{error:"assert requires a verb (e.g. find, describe, get errors)"}:{verbArgs:r,predicates:u,withinMs:n,negate:e,quiet:t,allowTimeout:i}}function N(s){return s[0]==="get"||s[0]==="debug"?w.has(s[1])?s[1]:null:s[0]==="do"||s[0]==="wait"?null:w.has(s[0])?s[0]:null}async function R(s){let u=[process.argv[1],...s,"--json"];return new Promise(n=>{let e=x(process.execPath,u,{stdio:["ignore","pipe","pipe"],env:process.env}),t="",i="";e.stdout.on("data",o=>t+=o.toString()),e.stderr.on("data",o=>i+=o.toString()),e.on("error",o=>{n({ok:!1,payload:null,reason:`spawn failed: ${o.message}`})}),e.on("close",o=>{if(o!==0){let a=i.trim().split(`
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import"./chunk-TI2ZOHON.js";import{spawn as x}from"child_process";var w=new Set(["describe","find","list","network","logs","count","tree","url","a11y","node","layout","keyboard","errors","warnings","requests","animations","animation","state","sample-color"]),S=new Set(["--exists","--empty","--negate","--quiet","--allow-timeout","!"]),q=new Set(["--count","--count-at-least","--count-at-most","--contains","--not-contains","--matches","--not-matches","--equals","--jq","--has-path","--within"]),P=new Set(["--path-equals"]);function j(s){let r=[],u=[],n=0,e=!1,t=!1,i=!1;for(let o=0;o<s.length;o++){let a=s[o];if(a==="--within"){let c=Number(s[o+1]);if(!Number.isFinite(c)||c<0)return{error:`--within requires a non-negative number, got: ${s[o+1]}`};n=c,o++;continue}if(a==="--negate"||a==="!"){e=!0;continue}if(a==="--quiet"){t=!0;continue}if(a==="--allow-timeout"){i=!0;continue}if(S.has(a)){u.push({kind:a,args:[]});continue}if(q.has(a)){let c=s[o+1];if(c==null)return{error:`${a} requires a value`};u.push({kind:a,args:[c]}),o++;continue}if(P.has(a)){let c=s[o+1],f=s[o+2];if(c==null||f==null)return{error:`${a} requires <path> <value>`};u.push({kind:a,args:[c,f]}),o+=2;continue}r.push(a)}return r.length===0?{error:"assert requires a verb (e.g. find, describe, get errors)"}:{verbArgs:r,predicates:u,withinMs:n,negate:e,quiet:t,allowTimeout:i}}function N(s){return s[0]==="get"||s[0]==="debug"?w.has(s[1])?s[1]:null:s[0]==="do"||s[0]==="wait"?null:w.has(s[0])?s[0]:null}async function R(s){let u=[process.argv[1],...s,"--json"];return new Promise(n=>{let e=x(process.execPath,u,{stdio:["ignore","pipe","pipe"],env:process.env}),t="",i="";e.stdout.on("data",o=>t+=o.toString()),e.stderr.on("data",o=>i+=o.toString()),e.on("error",o=>{n({ok:!1,payload:null,reason:`spawn failed: ${o.message}`})}),e.on("close",o=>{if(o!==0){let a=i.trim().split(`
3
3
  `).slice(-2).join(" | ").slice(0,200);n({ok:!1,payload:null,reason:`verb exited ${o}${a?`: ${a}`:""}`});return}if(!t.trim()){n({ok:!1,payload:null,reason:"verb produced no output"});return}try{let a=JSON.parse(t);n({ok:!0,payload:a})}catch{n({ok:!1,payload:null,reason:`verb output was not valid json: ${t.slice(0,120)}`})}})})}function y(s,r){let u=r.split(".").filter(e=>e.length>0),n=s;for(let e of u){if(n==null)return{found:!1};if(Array.isArray(n)){let t=Number(e);if(!Number.isInteger(t)||t<0||t>=n.length)return{found:!1};n=n[t];continue}if(typeof n=="object"){let t=n;if(!(e in t))return{found:!1};n=t[e];continue}return{found:!1}}return{found:!0,value:n}}function d(s){return Array.isArray(s)?s.length:s&&typeof s=="object"?Object.keys(s).length:null}async function A(s,r){let{kind:u,args:n}=s;switch(u){case"--exists":return r==null?{ok:!1,reason:"payload is null"}:d(r)===0?{ok:!1,reason:"payload is empty"}:{ok:!0,reason:"exists"};case"--empty":{if(r==null)return{ok:!0,reason:"payload is null"};let e=d(r);return e===0?{ok:!0,reason:"payload is empty"}:{ok:!1,reason:`payload has ${e} item(s)`}}case"--count":{let e=Number(n[0]),t=d(r);return t==null?{ok:!1,reason:`payload not countable (${typeof r})`}:{ok:t===e,reason:`count=${t}, want=${e}`}}case"--count-at-least":{let e=Number(n[0]),t=d(r);return t==null?{ok:!1,reason:"payload not countable"}:{ok:t>=e,reason:`count=${t}, want>=${e}`}}case"--count-at-most":{let e=Number(n[0]),t=d(r);return t==null?{ok:!1,reason:"payload not countable"}:{ok:t<=e,reason:`count=${t}, want<=${e}`}}case"--contains":{let e=n[0],t=JSON.stringify(r);return{ok:t.includes(e),reason:t.includes(e)?`contains "${e}"`:`missing "${e}"`}}case"--not-contains":{let e=n[0],t=JSON.stringify(r);return{ok:!t.includes(e),reason:t.includes(e)?`unexpected "${e}"`:`not contains "${e}"`}}case"--matches":{let e=new RegExp(n[0]),t=JSON.stringify(r),i=e.test(t);return{ok:i,reason:i?`matches /${n[0]}/`:`no match for /${n[0]}/`}}case"--not-matches":{let e=new RegExp(n[0]),t=JSON.stringify(r),i=!e.test(t);return{ok:i,reason:i?`not matches /${n[0]}/`:`unexpected /${n[0]}/`}}case"--equals":{let e=n[0],t=typeof r=="string"?r:typeof r=="number"||typeof r=="boolean"?String(r):JSON.stringify(r);return{ok:t===e,reason:`got=${JSON.stringify(t)}, want=${JSON.stringify(e)}`}}case"--has-path":{let e=y(r,n[0]);return{ok:e.found,reason:e.found?`path ${n[0]} present`:`path ${n[0]} missing`}}case"--path-equals":{let[e,t]=n,i=y(r,e);if(!i.found)return{ok:!1,reason:`path ${e} missing`};let o=typeof i.value=="string"||typeof i.value=="number"||typeof i.value=="boolean"?String(i.value):JSON.stringify(i.value);return{ok:o===t,reason:`${e}=${o}, want=${t}`}}case"--jq":{let e=n[0];try{let i=(await O(e,r)).trim();return{ok:i.length>0&&i!=="null"&&i!=="false"&&i!=='""',reason:`jq: ${i.slice(0,120)}`}}catch(t){throw new Error(`jq evaluation failed: ${t.message}`)}}default:return{ok:!1,reason:`unknown predicate ${u}`}}}function O(s,r){return new Promise((u,n)=>{let e=x("jq",[s],{stdio:["pipe","pipe","pipe"]}),t="",i="";e.stdout.on("data",o=>t+=o.toString()),e.stderr.on("data",o=>i+=o.toString()),e.on("error",n),e.on("close",o=>{if(o!==0){n(new Error(i.trim()||`jq exited ${o}`));return}u(t)}),e.stdin.end(JSON.stringify(r))})}async function T(s){(s[0]==="--help"||s[0]==="-h"||s.length===0)&&(J(),process.exit(s.length===0?2:0));let r=j(s);"error"in r&&(process.stderr.write(` assert: ${r.error}
4
4
  `),process.exit(2));let{verbArgs:u,predicates:n,withinMs:e,negate:t,quiet:i,allowTimeout:o}=r;N(u)||(process.stderr.write(` assert: unknown or non-read verb: ${u.join(" ")}
5
5
  supported: ${Array.from(w).sort().join(", ")}
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as t}from"./chunk-YNEFNAKF.js";import{d as s}from"./chunk-O7K44ZT6.js";import"./chunk-ERG3QCK4.js";import"./chunk-TWNBIOWX.js";function i(){console.log(`
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as t}from"./chunk-2344ZBLD.js";import{d as s}from"./chunk-6QMGV5H7.js";import"./chunk-TX53NA5W.js";import"./chunk-TI2ZOHON.js";function i(){console.log(`
3
3
  sootsim auth \u2014 inspect CLI auth
4
4
 
5
5
  usage:
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a,b,c,d}from"./chunk-KHIKG5LO.js";import"./chunk-TI2ZOHON.js";export{d as BETA_ASK_HEADLINE,b as BETA_LABEL,c as BETA_TAGLINE,a as IS_BETA};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{m as d}from"./chunk-TPD4GIHM.js";import"./chunk-4IBUPIN6.js";import{g as l,i as m,k as p}from"./chunk-TUMOXM4E.js";import"./chunk-5FQMI3PB.js";import"./chunk-DWL4WFZ2.js";import"./chunk-ERG3QCK4.js";import"./chunk-TWNBIOWX.js";function f(){console.log(`
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{m as d}from"./chunk-IUTSWOUM.js";import"./chunk-XJEIT5CH.js";import{g as l,i as m,k as p}from"./chunk-5LD4QHER.js";import"./chunk-BNUZWRON.js";import"./chunk-KPRSDBWU.js";import"./chunk-TX53NA5W.js";import"./chunk-TI2ZOHON.js";function f(){console.log(`
3
3
  sootsim do scan \u2014 inject a barcode scan
4
4
 
5
5
  usage:
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as r}from"./chunk-O7K44ZT6.js";var c=["ghs_","ghp_","gho_","ghu_","github_pat_"];function d(n){return!!(n&&n.length>=20&&c.some(t=>n.startsWith(t)))}function p(){let n=process.env.SOOT_INSTALLATION_TOKEN?.trim(),t=process.env.GITHUB_TOKEN?.trim(),e=n||t;if(!d(e))return null;let o=(process.env.SOOT_REPO||process.env.GITHUB_REPOSITORY||"").trim();if(!o)return null;let[i,s]=o.includes("/")?o.split("/",2):[null,null],u=(process.env.SOOT_REPO_ID||process.env.GITHUB_REPOSITORY_ID||"").trim(),l=(process.env.SOOT_INSTALLATION_ID||process.env.GITHUB_APP_INSTALLATION_ID||"").trim();return{kind:"github",token:e,repoId:o,repositoryId:u||null,owner:i||null,repo:s||null,installationId:l||null,source:n?"soot-runner":"github-actions"}}function g(){let n=process.env.SOOTSIM_API_KEY?.trim();if(n&&n.startsWith("sk_sootsim_"))return{kind:"api-key",secret:n,source:"env"};let t=p();if(t)return t;let e=r();return e?.token?{kind:"session",token:e.token,origin:e.origin}:null}function a(n){return n.kind==="api-key"?`Bearer ${n.secret}`:`Bearer ${n.token}`}function _(n){return!n||n.kind!=="github"?null:{repoId:n.repoId,owner:n.owner??void 0,repo:n.repo??void 0,installationId:n.installationId}}export{g as a,a as b,_ as c};
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as r}from"./chunk-6QMGV5H7.js";var c=["ghs_","ghp_","gho_","ghu_","github_pat_"];function d(n){return!!(n&&n.length>=20&&c.some(t=>n.startsWith(t)))}function p(){let n=process.env.SOOT_INSTALLATION_TOKEN?.trim(),t=process.env.GITHUB_TOKEN?.trim(),e=n||t;if(!d(e))return null;let o=(process.env.SOOT_REPO||process.env.GITHUB_REPOSITORY||"").trim();if(!o)return null;let[i,s]=o.includes("/")?o.split("/",2):[null,null],u=(process.env.SOOT_REPO_ID||process.env.GITHUB_REPOSITORY_ID||"").trim(),l=(process.env.SOOT_INSTALLATION_ID||process.env.GITHUB_APP_INSTALLATION_ID||"").trim();return{kind:"github",token:e,repoId:o,repositoryId:u||null,owner:i||null,repo:s||null,installationId:l||null,source:n?"soot-runner":"github-actions"}}function g(){let n=process.env.SOOTSIM_API_KEY?.trim();if(n&&n.startsWith("sk_sootsim_"))return{kind:"api-key",secret:n,source:"env"};let t=p();if(t)return t;let e=r();return e?.token?{kind:"session",token:e.token,origin:e.origin}:null}function a(n){return n.kind==="api-key"?`Bearer ${n.secret}`:`Bearer ${n.token}`}function _(n){return!n||n.kind!=="github"?null:{repoId:n.repoId,owner:n.owner??void 0,repo:n.repo??void 0,installationId:n.installationId}}export{g as a,a as b,_ as c};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as fe,c as me,d as ge,e as Ze,f as we,g as ye,h as Xe,i as be,j as Qe}from"./chunk-SPEEWUAK.js";import{a as Ye}from"./chunk-W7RH3GDB.js";import{a as tt}from"./chunk-DOCQ4YBT.js";import{a as et}from"./chunk-OHRSRPEB.js";import{h as Ge,p as ze,r as Ke,v as qe}from"./chunk-FMITPB4T.js";import{f as Ce}from"./chunk-HTX3YVCJ.js";import{a as Le}from"./chunk-KOARSZSJ.js";import{h as he,m as Ve}from"./chunk-TPD4GIHM.js";import{I as J,m as Ne,n as He,o as Ue,p as We}from"./chunk-4IBUPIN6.js";import{g as ue,h as pe,i as je}from"./chunk-TUMOXM4E.js";import{a as Je}from"./chunk-4RU6YTEP.js";import{a as Oe,b as ce}from"./chunk-7SYXBGM2.js";import{d as de,e as Be}from"./chunk-DWL4WFZ2.js";import{g as _e,h as De}from"./chunk-AOUNFYEN.js";import*as k from"fs";import{createHash as Ht,randomUUID as Ut}from"node:crypto";import{tmpdir as ie}from"os";import*as g from"path";import*as S from"fs";import*as b from"path";var Tt="inset 0 0 0 0.5px #000, inset 0 0 0 2px #757575, inset 0 0 0 5px #212121",it=1;function Et(n){let e=De(n),t=e.scale,r=e.statusBarHeight>0&&!e.dynamicIsland&&e.homeIndicatorHeight===0&&e.cornerRadius===0,i=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,u=it,p=a+l*2,m=s+it*2,x=l+(r?29:e.bezelWidth),w=r?111:e.bezelWidth,P=r?52:e.cornerRadius+e.bezelWidth,_=[{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:n,renderScale:t,outerWidth:Math.round(p*t),outerHeight:Math.round(m*t),logicalOuterWidth:p,logicalOuterHeight:m,logicalFrameWidth:a,logicalFrameHeight:s,logicalFrameLeft:l,logicalFrameTop:u,logicalScreenWidth:i,logicalScreenHeight:o,logicalScreenLeft:x,logicalScreenTop:w,logicalScreenRadius:r?0:e.cornerRadius,logicalFrameRadius:P,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:Tt,buttons:_,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 Ft(n){let e=n.side==="right",t=e?"inset(-3px -3px -3px 0)":"inset(-3px 0 -3px -3px)";return`
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as fe,c as me,d as ge,e as Ze,f as we,g as ye,h as Xe,i as be,j as Qe}from"./chunk-XQP4TU6P.js";import{a as Ye}from"./chunk-QPZW76ZB.js";import{a as tt}from"./chunk-CZZZC3BU.js";import{a as et}from"./chunk-WEBUMXLD.js";import{h as Ge,p as ze,r as Ke,v as qe}from"./chunk-4RHFQCED.js";import{f as Ce}from"./chunk-USW3U45B.js";import{a as Le}from"./chunk-AYY7JBXA.js";import{h as he,m as Ve}from"./chunk-IUTSWOUM.js";import{I as J,m as Ne,n as He,o as Ue,p as We}from"./chunk-XJEIT5CH.js";import{g as ue,h as pe,i as je}from"./chunk-5LD4QHER.js";import{a as Je}from"./chunk-RRFWPEQ6.js";import{a as Oe,b as ce}from"./chunk-6LJUMA3J.js";import{d as de,e as Be}from"./chunk-KPRSDBWU.js";import{g as _e,h as De}from"./chunk-T7CWPTU7.js";import*as k from"fs";import{createHash as Ht,randomUUID as Ut}from"node:crypto";import{tmpdir as ie}from"os";import*as g from"path";import*as S from"fs";import*as b from"path";var Tt="inset 0 0 0 0.5px #000, inset 0 0 0 2px #757575, inset 0 0 0 5px #212121",it=1;function Et(n){let e=De(n),t=e.scale,r=e.statusBarHeight>0&&!e.dynamicIsland&&e.homeIndicatorHeight===0&&e.cornerRadius===0,i=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,u=it,p=a+l*2,m=s+it*2,x=l+(r?29:e.bezelWidth),w=r?111:e.bezelWidth,P=r?52:e.cornerRadius+e.bezelWidth,_=[{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:n,renderScale:t,outerWidth:Math.round(p*t),outerHeight:Math.round(m*t),logicalOuterWidth:p,logicalOuterHeight:m,logicalFrameWidth:a,logicalFrameHeight:s,logicalFrameLeft:l,logicalFrameTop:u,logicalScreenWidth:i,logicalScreenHeight:o,logicalScreenLeft:x,logicalScreenTop:w,logicalScreenRadius:r?0:e.cornerRadius,logicalFrameRadius:P,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:Tt,buttons:_,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 Ft(n){let e=n.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="
@@ -559,7 +559,7 @@ flow extension:
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
561
  `),M&&(console.log(" partial profile:"),lt(M)),T&&console.log(` partial video: ${T}`);try{let c=d.lastFailedStep,y=c?`step-${String(c.index+1).padStart(2,"0")}-${c.kind}`:"unstaged",$=g.join(s,y);await d.captureFailureBundle($,{error:h,stepIndex:c?.index,stepKind:c?.kind,stepTarget:c?.target}),le=$,console.log(` failure bundle: ${$}`),console.log(" (contents: screenshot.png, describe.json, a11y.txt, tree.txt, console.json, error.json)")}catch(c){try{let y=g.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 Ve(F,{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}`:""}`}),j=1}if(await d.liveStatus?.end(j===0?"passed":"failed"),w&&(j===0||T||O))try{let h=await Jt(O??[]),c=["--origin",P,"--events",h];_&&c.push("--public-origin",_),T&&c.push("--video",T),W&&c.push("--screenshot",W),T&&B&&Number.isFinite(B)&&(c.push("--video-duration-ms",String(Math.round(B))),c.push("--recorded-duration-ms",String(Math.round(B))));let y=d.getLastRecordingStartedAtMs();y&&Number.isFinite(y)&&c.push("--recording-started-at-ms",String(Math.round(y))),v.wsPort&&c.push("--port",String(v.wsPort)),d.simId&&c.push("--sim",d.simId),dt&&c.push("--open"),Ie&&c.push("--owner",Ie),$e&&c.push("--repo",$e),c.push("--run-scope",ut),H&&c.push("--billing-kind",H),console.log(`
562
- preparing preview upload\u2026`);let $=d.getFlowTraceSteps();$.length>0&&c.push("--timeline-events",await Gt($)),le&&c.push("--failure-bundle",le);let V=d.getLastRecordingFrameStats();V&&c.push("--trace-frame-stats",await zt(V));let{runUpload:L}=await import("./upload-RNDBU5AE.js");Ee=await L(c,{})}catch(h){console.error(` preview upload failed: ${h?.message||h}`),j=1}return Fe=d.getFlowTraceSteps(),F.close(),se?(d.simId&&ae.add(d.simId),await Vt(v.wsPort,v.commandTimeoutMs,[...ae])):d.simId&&d.simId!==q&&Be(d.simId),await ce(),j}async function Vt(n,e,t){let r=[...new Set(t.filter(Boolean))];if(r.length===0)return;let i=pe(n,{commandTimeoutMs:e});try{let o=await i.listSims(),a=r.filter(l=>o.some(u=>u.id===l&&u.readyState==="open"));if(a.length===0)return;let s=await qe(i,n,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{i.close()}}async function Jt(n){let{gzipSync:e}=await import("zlib"),t=n.map(o=>JSON.stringify(o)).join(`
562
+ preparing preview upload\u2026`);let $=d.getFlowTraceSteps();$.length>0&&c.push("--timeline-events",await Gt($)),le&&c.push("--failure-bundle",le);let V=d.getLastRecordingFrameStats();V&&c.push("--trace-frame-stats",await zt(V));let{runUpload:L}=await import("./upload-UQRYTSL2.js");Ee=await L(c,{})}catch(h){console.error(` preview upload failed: ${h?.message||h}`),j=1}return Fe=d.getFlowTraceSteps(),F.close(),se?(d.simId&&ae.add(d.simId),await Vt(v.wsPort,v.commandTimeoutMs,[...ae])):d.simId&&d.simId!==q&&Be(d.simId),await ce(),j}async function Vt(n,e,t){let r=[...new Set(t.filter(Boolean))];if(r.length===0)return;let i=pe(n,{commandTimeoutMs:e});try{let o=await i.listSims(),a=r.filter(l=>o.some(u=>u.id===l&&u.readyState==="open"));if(a.length===0)return;let s=await qe(i,n,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{i.close()}}async function Jt(n){let{gzipSync:e}=await import("zlib"),t=n.map(o=>JSON.stringify(o)).join(`
563
563
  `)+(n.length?`
564
564
  `:""),r=e(Buffer.from(t,"utf8")),i=g.join(ie(),`sootsim-events-${Date.now()}.jsonl.gz`);return k.writeFileSync(i,r),console.log(` events: ${n.length} written to ${i} (${r.length} bytes gz)`),i}async function Gt(n){let{gzipSync:e}=await import("zlib"),t=n.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
  `)+`
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import{createInterface as i}from"readline";var c=()=>i({input:process.stdin,output:process.stdout});function s(o){return new Promise(n=>{let r=c();r.question(o,t=>{r.close(),n(t.trim())})})}async function u(o,n=!0){let r=n?"[Y/n]":"[y/N]";if(!process.stdin.isTTY)return console.log(` ${o} ${r} ${n?"y":"n"} (non-interactive)`),n;let t=await s(` ${o} ${r} `);return t===""?n:t.toLowerCase().startsWith("y")}async function a(o,n){console.log(`
3
3
  ${o}
4
4
  `);for(let e=0;e<n.length;e++)console.log(` ${e+1}. ${n[e]}`);if(console.log(),!process.stdin.isTTY)return console.log(` choose [1-${n.length}]: 1 (non-interactive)`),0;let r=await s(` choose [1-${n.length}]: `),t=parseInt(r,10);return t>=1&&t<=n.length?t-1:0}export{u as a,a as b};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as j,b as ne,c as re,d as xe,e as ke,g as Pe}from"./chunk-HTX3YVCJ.js";import{a as Me,b as _e}from"./chunk-TWNZ24EL.js";import{a as Ce,b as se,c as Ee}from"./chunk-KRJRWLOW.js";import{m as T}from"./chunk-TPD4GIHM.js";import{m as Ue,o as Te}from"./chunk-4IBUPIN6.js";import{a as Re,b as Oe,c as ie,e as Be,f as De,g as C,h as v,i as E}from"./chunk-TUMOXM4E.js";import{b as Ie,l as ce}from"./chunk-QXDO6QT5.js";import{a as R,b as ae}from"./chunk-4RU6YTEP.js";import{d as le}from"./chunk-TBLMSWZ6.js";import{d as _,e as b,f as U}from"./chunk-DWL4WFZ2.js";import{H as Se,M as te,O as W,l as ve}from"./chunk-ERG3QCK4.js";import{g as oe,i as $e}from"./chunk-AOUNFYEN.js";import{spawn as je}from"node:child_process";import D from"node:fs";import ut from"node:os";import M from"node:path";import{WebSocket as pt}from"ws";function rt(e){return e.replace(/^\[|\]$/g,"").toLowerCase()}function K(e){let t=rt(e);return t==="localhost"||t.endsWith(".localhost")||t==="0.0.0.0"||t==="::1"||/^127(?:\.\d{1,3}){3}$/.test(t)}function Le(e){return new Error(`could not resolve a native bundle for ${e}. pass an explicit bundle URL or open Connect and choose the app there.`)}function st(e,t){return e?.includes("/one/metro-entry.bundle")?"one":typeof t=="string"&&t?"expo":"unknown"}function Ne(e,t,o){return`${e}//${t}:${o}`}function it(e){if(typeof window>"u")return!1;try{let t=new URL(e);return K(t.hostname)&&K(window.location.hostname)&&t.origin!==window.location.origin}catch{return!1}}async function Ae(e,t){let o={...t,cache:t?.cache??"no-store"};return it(e)?fetch(`/__fetch-proxy?url=${encodeURIComponent(e)}`,o):fetch(e,o)}function at(e){return e==="https:"?443:80}function lt(e){let t=e.pathname||"/";return(t==="/"||t==="")&&!e.search&&!e.hash}async function ct(e){try{let t=await fetch("/__server-scan",{cache:"no-store"});if(!t.ok||!(t.headers.get("content-type")||"").toLowerCase().includes("json"))return null;let o=await t.json();if(!Array.isArray(o))return null;let n=o.find(r=>!!r&&typeof r=="object"&&r.port===e&&typeof r.bundleUrl=="string");return n?{bundleUrl:re(n.bundleUrl),port:e,framework:typeof n.framework=="string"?n.framework:"unknown",projectName:typeof n.projectName=="string"?n.projectName:void 0}:null}catch{return null}}async function Fe(e,t){let o=e.replace(/\/+$/,"");try{if(K(new URL(o).hostname)){let n=await ct(t);if(n)return n}}catch{}try{let n=await Ae(`${o}/`,{headers:{"expo-platform":"ios"}});if(n.ok){let r=await n.json(),s=r?.extra?.expoClient||r?.extra||{},i=typeof r?.launchAsset?.url=="string"?r.launchAsset.url:void 0;if(i||s.name)return{bundleUrl:re(i||`${o}${ne}`),port:t,framework:st(i,s.sdkVersion),projectName:s.name}}}catch{}try{let n=await Ae(`${o}/status`);if(n.ok&&(await n.text()).includes("packager-status:running"))return{bundleUrl:`${o}${ne}`,port:t,framework:"metro"}}catch{}return null}async function dt(e){return Fe(Ne("http:","localhost",e),e)}async function He(e){let t=e.trim();if(/^\d+$/.test(t)){let a=parseInt(t,10),l=await dt(a);if(l)return l;throw Le(`localhost:${a}`)}let o=t.startsWith("http")?t:`http://${t}`,n;try{n=new URL(o)}catch{throw new Error(`could not parse "${e}". pass a dev-server port, a dev-server base URL, or a full bundle URL.`)}let r=n.protocol||"http:",s=n.port?parseInt(n.port,10):at(r),i=Ne(r,n.hostname,s);if(lt(n)){let a=await Fe(i,s);if(a)return a;throw Le(i)}return{bundleUrl:n.toString(),port:s,framework:"unknown"}}function io(){console.error(" no sootsim desktop companion found."),console.error(""),console.error(" install the desktop app:"),console.error(" sootsim desktop install"),console.error(""),console.error(" or run setup to install the background daemon:"),console.error(" sootsim setup"),console.error("")}function We(e){let t=R();if(console.log(` note: no sootsim bridge detected on port ${e}`),t){console.log(" launch the installed companion with:"),console.log(" sootsim desktop");return}console.log(""),console.log(" run `sootsim setup` to install the background daemon,"),console.log(" or run `sootsim serve` in another shell for a foreground bridge.")}function mt(e){console.error(""),console.error(` no sim is connected to the sootsim bridge on port ${e}.`),console.error(""),console.error(" start your app dev server, then open it in sootsim:"),console.error(" npx expo start --localhost --port 8081"),console.error(" sootsim open 8081"),console.error(""),console.error(" then inspect the live app:"),console.error(" sootsim describe")}async function ao(e,t,o){let n=[];try{n=await e.listSims()}catch{}if(console.error(""),n.length===0){mt(t);return}console.error(` no sim with id "${o}" is connected to the bridge on port ${t}.`),console.error(""),console.error(" connected sims:");for(let r of n){let s=[r.isPrimary?"primary":null,r.readyState,r.userVisible===!1?"hidden":r.userVisible===!0?"visible":null,r.userFocused?"focused":null].filter(Boolean).join(", ");console.error(` ${r.id} (${s})`)}console.error(""),console.error(" pass a valid --sim id, or run `sootsim list` to see all sessions.")}var ft=12e4,Ke=100,ht=5e3,ze=1e4,gt={rn:"/rn",connectrn:"/rn","connect-rn":"/rn",clock:"/app/clock","native-ui":"/app/native-ui",tamagui:"/app/tamagui",settings:"/app/settings",photos:"/app/photos",camera:"/app/camera"};function $(e){return new Promise(t=>setTimeout(t,e))}function qe(e){let t=process.env[e]?.trim();if(!t)return null;let o=Number(t);return Number.isInteger(o)&&o>0?o:null}function wt(){let e=qe("SOOTSIM_DRIVER_CONNECT_TIMEOUT_MS")??qe("SOOTSIM_PW_CONNECT_TIMEOUT_MS")??ft;return{timeoutMs:e,hostTimeoutMs:e+ht,intervalMs:Ke,attempts:Math.max(1,Math.ceil(e/Ke))}}function bt(e){return e==="chromium"||e==="electron"||e==="playwright"||e==="system"}function yt(e,t){return e.includes("--headless")?!0:e.includes("--headed")?!1:t==="playwright"&&process.platform==="linux"&&!process.env.DISPLAY&&!process.env.WAYLAND_DISPLAY?(console.error(" no display detected \u2192 running playwright headless (override with --headed)"),!0):!1}function G(e){return e.trim()}var Qe=/^[A-Za-z][A-Za-z0-9+.-]*:/;function vt(e){let t=e.trim();if(!t)throw new Error("expected <url-or-route>");return Qe.test(t)||t.startsWith("/")?t:`/${t}`}function St(e){return e!==null&&typeof e=="object"}function $t(e){let t=e.trim();return t?t.startsWith("/")?!0:Qe.test(t)?!/^https?:\/\//i.test(t):!1:!1}async function xt(e){if(await z(e,250))return e;let t=te();if(t&&W(t)&&await z(t.bridgePort,500))return t.bridgePort;if(t&&W(t))throw new Error(`sootsim bridge lockfile is fresh (port ${t.bridgePort}) but the bridge is not reachable. run \`sootsim daemon restart\` or \`sootsim daemon uninstall\`.`);await kt();let o=It(["serve","--quiet","--port",String(e)]),n=null;o.once("exit",(s,i)=>{n=String(s??i??"unknown")}),o.unref();let r=Date.now()+ze;for(;Date.now()<r;){let s=te();if(s&&W(s)&&await z(s.bridgePort,250))return console.error(` started local bridge on port ${s.bridgePort}; run \`sootsim setup\` to install the background daemon`),s.bridgePort;if(await z(e,250))return console.error(` started local bridge on port ${e}; run \`sootsim setup\` to install the background daemon`),e;if(n)throw new Error(`sootsim bridge exited before becoming ready (exit ${n})`);await $(150)}throw new Error(`sootsim bridge did not start within ${Math.round(ze/1e3)}s`)}async function kt(){let e=Se();if(e&&D.existsSync(ve(e)))return;console.error(" installing sootsim engine runtime...");let{runRuntime:t}=await import("./runtime-BFBAWZDT.js");await t(["install"],{})}function It(e){let t=process.argv[1];return t&&D.existsSync(t)?je(process.execPath,[t,...e],{detached:!0,stdio:"ignore",env:process.env}):je("sootsim",e,{detached:!0,stdio:"ignore",env:process.env})}function z(e,t){return new Promise(o=>{let n=new pt(`ws://127.0.0.1:${e}`,{handshakeTimeout:t}),r=!1,s=i=>{if(!r){r=!0;try{n.close()}catch{}o(i)}};n.once("open",()=>s(!0)),n.once("error",()=>s(!1)),setTimeout(()=>s(!1),t)})}function ue(e){try{let t=new URL(e),o=t.pathname.replace(/\/+$/,"")||"/";return t.searchParams.has("open")||t.searchParams.has("port")||t.searchParams.has("bundle")||t.searchParams.has("demo")||t.pathname.includes("/sootsim/index.html")||o==="/sootsim"||t.pathname==="/__soot"||t.pathname==="/__soot/"||o==="/rn"||/^\/rn\/[^/]+$/i.test(o)||/^\/app\/[^/]+$/i.test(o)||o==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(o)||/^\/__soot\/app\/[^/]+$/i.test(o)}catch{return!1}}function Pt(e){try{let t=new URL(e,"http://sootsim.local");if(t.origin!=="http://sootsim.local")return!1;let o=t.pathname.replace(/\/+$/,"")||"/";return o==="/rn"||/^\/rn\/[^/]+$/i.test(o)||/^\/app\/[^/]+$/i.test(o)||o==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(o)||/^\/__soot\/app\/[^/]+$/i.test(o)}catch{return!1}}function Ct(e,t){let o=new URL(e,"http://sootsim.local"),n=new URL(t),r=V(n.pathname),s=o.pathname.startsWith("/__soot/")?o.pathname.slice(7):o.pathname;return n.pathname=`${r}${s}`,n.search=o.search,n.hash=o.hash,n.toString()}function Et(e){try{let t=new URL(e).pathname.replace(/\/+$/,"")||"/";return/^\/preview\/[^/]+$/.test(t)||/^\/build\/.+/.test(t)}catch{return!1}}async function Ro(e){let t=G(e);return(await Ye(t)).bundleUrl}function Mt(e){try{let t=new URL(e.startsWith("http")?e:`http://${e}`),o=t.pathname||"/";if(o!=="/"&&o!==""||t.search||t.hash||!/^(localhost|127\.0\.0\.1|\[::1\]|::1)$/i.test(t.hostname))return null;let n=t.port?Number(t.port):t.protocol==="https:"?443:80;return Number.isFinite(n)&&n>0?n:null}catch{return null}}async function Ye(e){let t=G(e),o=/^\d+$/.test(t)?Number(t):Mt(t);if(o&&o>0){let n=await ke(o);if(n)return{bundleUrl:n.bundleUrl,port:n.port,framework:n.framework,projectName:n.projectName}}return He(t)}function V(e){let t=e.replace(/\/+$/,"")||"/";return t==="/__soot"||t.startsWith("/__soot/")?"/__soot":""}function _t(e,t){let o=G(e),n=new URL(t),r=V(n.pathname);return n.pathname=`${r}/rn`,n.searchParams.delete("bundle"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.delete("open"),n.searchParams.delete("port"),/^\d+$/.test(o)?n.pathname=`${r}/rn/${o}`:(n.pathname=`${r}/rn`,n.searchParams.set("open",o)),n.toString()}function Ut(e){let t=G(e);return/^\d+$/.test(t)||/^https?:\/\//i.test(t)?!0:/^(localhost|127\.0\.0\.1|\[::1\]|[^/]+\.localhost):\d+(?:\/.*)?$/i.test(t)}async function Tt(e,t,o={}){let n=await Ye(e),r=new URL(t),s=V(r.pathname);r.pathname=`${s}/rn`,r.searchParams.delete("open"),r.searchParams.delete("port"),r.searchParams.delete("demo"),r.searchParams.delete("app");let i=o.hot===void 0?n.bundleUrl:xe(n.bundleUrl,o.hot);return r.searchParams.set("bundle",i),r.toString()}function Rt(e){return e.startsWith("~/")?M.join(ut.homedir(),e.slice(2)):M.isAbsolute(e)?e:M.resolve(process.cwd(),e)}function Ot(e){let t={},o={};for(let r=0;r<e.length;r++){if(e[r]==="--replace"){let s=e[r+1];s||(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let i=s.indexOf("=");(i<=0||i===s.length-1)&&(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let a=s.slice(0,i).trim(),l=Rt(s.slice(i+1).trim());D.existsSync(l)||(console.error(` sootsim open: replacement file not found: ${l}`),process.exit(1)),t[a]={file:l},r++;continue}if(e[r]==="--remap"){let s=e[r+1],i=s?s.indexOf("="):-1;(!s||i<=0||i===s.length-1)&&(console.error(" sootsim open: --remap expects <host:port>=<host:port>"),process.exit(1)),o[s.slice(0,i).trim()]=s.slice(i+1).trim(),r++;continue}}let n={};return Object.keys(t).length>0&&(n.modules=t),Object.keys(o).length>0&&(n.network={remap:o}),n.modules||n.network?n:void 0}function Ze(){return Re().shellBaseUrl}async function Bt(e){try{let t=new URL(e),o=t.searchParams.get("bundle")||"";if(!o)return e;let n=process.env.SOOT_REPO_DIR||await se(o)||void 0,r=Ce({bundleUrl:o,repoDir:n});if(r.length===0)return e;let s=await Dt(r);return s.length===0?e:(t.searchParams.set("appFonts",Ee(s)),t.toString())}catch{return e}}async function Dt(e){let t=await Promise.all(e.map(async n=>{let r=new AbortController,s=setTimeout(()=>r.abort(),1500);try{let i=await fetch(n.url,{method:"HEAD",signal:r.signal});return i.status>=200&&i.status<400?n:null}catch{return null}finally{clearTimeout(s)}})),o=[];for(let n of t)n!==null&&o.push(n);return o}async function Lt(e,t,o={}){if(!e)return new URL(t).toString();if(ue(e))return new URL(e).toString();if(Pt(e))return Ct(e,t);let n=gt[e.toLowerCase()];if(n){let r=new URL(t),s=V(r.pathname);return r.pathname=`${s}${n}`,r.toString()}return Ut(e)?Tt(e,t,o):_t(e,t)}async function At(e){try{let t=new URL(e),o=t.searchParams.get("bundle")||"";if(!o)return e;let n=process.env.SOOT_REPO_DIR||await se(o)||void 0,r=Me({bundleUrl:o,repoDir:n});return!r||r.imageUrl&&!await Nt(r.imageUrl)?e:(t.searchParams.set("appSplash",_e(r)),t.toString())}catch{return e}}async function Nt(e){let t=new AbortController,o=setTimeout(()=>t.abort(),1500);try{let n=await fetch(e,{method:"HEAD",signal:t.signal});return n.status>=200&&n.status<400}catch{return!1}finally{clearTimeout(o)}}async function q(e,t=Ze(),o={}){let n=await Lt(e,t,o),r=await At(await Bt(n));if(!o.device)return r;let s=new URL(r);return s.searchParams.set("device",o.device),s.toString()}function Ge(e,t){let o=e?.url||e?.origin||t;try{let n=new URL(o);return n.searchParams.delete("bundle"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.delete("open"),n.searchParams.delete("port"),n.searchParams.delete("inspectOpen"),n.searchParams.delete("appFonts"),n.searchParams.delete("appSplash"),n.toString()}catch{return t}}async function Ft(e,t,o,n={}){let r=new URL(await q(e,t,n));return r.searchParams.set("inspectOpen",o),r.toString()}async function Ht(e,t,o,n={}){let r=n.attempts??30,s=n.intervalMs??500,i=n.minNodeCount??10;for(let a=0;a<r;a++){let l=v(e,{commandTimeoutMs:t,simId:o,simIdSource:"flag"});try{let d=await l.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount()) || 0)()"});if(typeof d=="number"&&d>i)return{bridge:l,count:d}}catch{}l.close(),await $(s)}return null}function Wt(e){if(!e)return null;try{let t=new URL(e);if(t.searchParams.has("bundle")){let o=t.searchParams.get("bundle")||"";try{let n=new URL(o),r=n.pathname.length>36?`...${n.pathname.slice(-36)}`:n.pathname;return`bundle ${n.host}${r}`}catch{return"bundle"}}return t.searchParams.has("port")?`connect :${t.searchParams.get("port")||""}`:t.searchParams.has("open")?`connect ${t.searchParams.get("open")||""}`:t.searchParams.has("demo")?`demo ${t.searchParams.get("demo")||"default"}`:t.pathname.includes("/sootsim/index.html")||t.pathname==="/sootsim/"||t.pathname==="/sootsim"?"embedded sootsim":null}catch{return null}}function jt(e){let t=e.indexOf(":");if(t<=0)return e.length>24?`${e.slice(0,21)}\u2026`:e;let o=e.slice(0,t),n=e.slice(t+1),r=n.length>12?`${n.slice(0,8)}\u2026`:n;return o==="AGENTBUS_SESSION"||o==="CLAUDE_CODE_SESSION_ID"||o==="CODEX_THREAD_ID"?`agent ${r}`:`${o} ${r}`}function Oo(e,t){if(e.length===0){console.log(" no sims connected");return}console.log(` connected sims (${e.length}):
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as j,b as ne,c as re,d as xe,e as ke,g as Pe}from"./chunk-USW3U45B.js";import{a as Me,b as _e}from"./chunk-USSUXBPG.js";import{a as Ce,b as se,c as Ee}from"./chunk-5P6QAHAI.js";import{m as T}from"./chunk-IUTSWOUM.js";import{m as Ue,o as Te}from"./chunk-XJEIT5CH.js";import{a as Re,b as Oe,c as ie,e as Be,f as De,g as C,h as v,i as E}from"./chunk-5LD4QHER.js";import{b as Ie,l as ce}from"./chunk-L3CQVAWX.js";import{a as R,b as ae}from"./chunk-RRFWPEQ6.js";import{d as le}from"./chunk-GTRGDGRK.js";import{d as _,e as b,f as U}from"./chunk-KPRSDBWU.js";import{H as Se,M as te,O as W,l as ve}from"./chunk-TX53NA5W.js";import{g as oe,i as $e}from"./chunk-T7CWPTU7.js";import{spawn as je}from"node:child_process";import D from"node:fs";import ut from"node:os";import M from"node:path";import{WebSocket as pt}from"ws";function rt(e){return e.replace(/^\[|\]$/g,"").toLowerCase()}function K(e){let t=rt(e);return t==="localhost"||t.endsWith(".localhost")||t==="0.0.0.0"||t==="::1"||/^127(?:\.\d{1,3}){3}$/.test(t)}function Le(e){return new Error(`could not resolve a native bundle for ${e}. pass an explicit bundle URL or open Connect and choose the app there.`)}function st(e,t){return e?.includes("/one/metro-entry.bundle")?"one":typeof t=="string"&&t?"expo":"unknown"}function Ne(e,t,o){return`${e}//${t}:${o}`}function it(e){if(typeof window>"u")return!1;try{let t=new URL(e);return K(t.hostname)&&K(window.location.hostname)&&t.origin!==window.location.origin}catch{return!1}}async function Ae(e,t){let o={...t,cache:t?.cache??"no-store"};return it(e)?fetch(`/__fetch-proxy?url=${encodeURIComponent(e)}`,o):fetch(e,o)}function at(e){return e==="https:"?443:80}function lt(e){let t=e.pathname||"/";return(t==="/"||t==="")&&!e.search&&!e.hash}async function ct(e){try{let t=await fetch("/__server-scan",{cache:"no-store"});if(!t.ok||!(t.headers.get("content-type")||"").toLowerCase().includes("json"))return null;let o=await t.json();if(!Array.isArray(o))return null;let n=o.find(r=>!!r&&typeof r=="object"&&r.port===e&&typeof r.bundleUrl=="string");return n?{bundleUrl:re(n.bundleUrl),port:e,framework:typeof n.framework=="string"?n.framework:"unknown",projectName:typeof n.projectName=="string"?n.projectName:void 0}:null}catch{return null}}async function Fe(e,t){let o=e.replace(/\/+$/,"");try{if(K(new URL(o).hostname)){let n=await ct(t);if(n)return n}}catch{}try{let n=await Ae(`${o}/`,{headers:{"expo-platform":"ios"}});if(n.ok){let r=await n.json(),s=r?.extra?.expoClient||r?.extra||{},i=typeof r?.launchAsset?.url=="string"?r.launchAsset.url:void 0;if(i||s.name)return{bundleUrl:re(i||`${o}${ne}`),port:t,framework:st(i,s.sdkVersion),projectName:s.name}}}catch{}try{let n=await Ae(`${o}/status`);if(n.ok&&(await n.text()).includes("packager-status:running"))return{bundleUrl:`${o}${ne}`,port:t,framework:"metro"}}catch{}return null}async function dt(e){return Fe(Ne("http:","localhost",e),e)}async function He(e){let t=e.trim();if(/^\d+$/.test(t)){let a=parseInt(t,10),l=await dt(a);if(l)return l;throw Le(`localhost:${a}`)}let o=t.startsWith("http")?t:`http://${t}`,n;try{n=new URL(o)}catch{throw new Error(`could not parse "${e}". pass a dev-server port, a dev-server base URL, or a full bundle URL.`)}let r=n.protocol||"http:",s=n.port?parseInt(n.port,10):at(r),i=Ne(r,n.hostname,s);if(lt(n)){let a=await Fe(i,s);if(a)return a;throw Le(i)}return{bundleUrl:n.toString(),port:s,framework:"unknown"}}function io(){console.error(" no sootsim desktop companion found."),console.error(""),console.error(" install the desktop app:"),console.error(" sootsim desktop install"),console.error(""),console.error(" or run setup to install the background daemon:"),console.error(" sootsim setup"),console.error("")}function We(e){let t=R();if(console.log(` note: no sootsim bridge detected on port ${e}`),t){console.log(" launch the installed companion with:"),console.log(" sootsim desktop");return}console.log(""),console.log(" run `sootsim setup` to install the background daemon,"),console.log(" or run `sootsim serve` in another shell for a foreground bridge.")}function mt(e){console.error(""),console.error(` no sim is connected to the sootsim bridge on port ${e}.`),console.error(""),console.error(" start your app dev server, then open it in sootsim:"),console.error(" npx expo start --localhost --port 8081"),console.error(" sootsim open 8081"),console.error(""),console.error(" then inspect the live app:"),console.error(" sootsim describe")}async function ao(e,t,o){let n=[];try{n=await e.listSims()}catch{}if(console.error(""),n.length===0){mt(t);return}console.error(` no sim with id "${o}" is connected to the bridge on port ${t}.`),console.error(""),console.error(" connected sims:");for(let r of n){let s=[r.isPrimary?"primary":null,r.readyState,r.userVisible===!1?"hidden":r.userVisible===!0?"visible":null,r.userFocused?"focused":null].filter(Boolean).join(", ");console.error(` ${r.id} (${s})`)}console.error(""),console.error(" pass a valid --sim id, or run `sootsim list` to see all sessions.")}var ft=12e4,Ke=100,ht=5e3,ze=1e4,gt={rn:"/rn",connectrn:"/rn","connect-rn":"/rn",clock:"/app/clock","native-ui":"/app/native-ui",tamagui:"/app/tamagui",settings:"/app/settings",photos:"/app/photos",camera:"/app/camera"};function $(e){return new Promise(t=>setTimeout(t,e))}function qe(e){let t=process.env[e]?.trim();if(!t)return null;let o=Number(t);return Number.isInteger(o)&&o>0?o:null}function wt(){let e=qe("SOOTSIM_DRIVER_CONNECT_TIMEOUT_MS")??qe("SOOTSIM_PW_CONNECT_TIMEOUT_MS")??ft;return{timeoutMs:e,hostTimeoutMs:e+ht,intervalMs:Ke,attempts:Math.max(1,Math.ceil(e/Ke))}}function bt(e){return e==="chromium"||e==="electron"||e==="playwright"||e==="system"}function yt(e,t){return e.includes("--headless")?!0:e.includes("--headed")?!1:t==="playwright"&&process.platform==="linux"&&!process.env.DISPLAY&&!process.env.WAYLAND_DISPLAY?(console.error(" no display detected \u2192 running playwright headless (override with --headed)"),!0):!1}function G(e){return e.trim()}var Qe=/^[A-Za-z][A-Za-z0-9+.-]*:/;function vt(e){let t=e.trim();if(!t)throw new Error("expected <url-or-route>");return Qe.test(t)||t.startsWith("/")?t:`/${t}`}function St(e){return e!==null&&typeof e=="object"}function $t(e){let t=e.trim();return t?t.startsWith("/")?!0:Qe.test(t)?!/^https?:\/\//i.test(t):!1:!1}async function xt(e){if(await z(e,250))return e;let t=te();if(t&&W(t)&&await z(t.bridgePort,500))return t.bridgePort;if(t&&W(t))throw new Error(`sootsim bridge lockfile is fresh (port ${t.bridgePort}) but the bridge is not reachable. run \`sootsim daemon restart\` or \`sootsim daemon uninstall\`.`);await kt();let o=It(["serve","--quiet","--port",String(e)]),n=null;o.once("exit",(s,i)=>{n=String(s??i??"unknown")}),o.unref();let r=Date.now()+ze;for(;Date.now()<r;){let s=te();if(s&&W(s)&&await z(s.bridgePort,250))return console.error(` started local bridge on port ${s.bridgePort}; run \`sootsim setup\` to install the background daemon`),s.bridgePort;if(await z(e,250))return console.error(` started local bridge on port ${e}; run \`sootsim setup\` to install the background daemon`),e;if(n)throw new Error(`sootsim bridge exited before becoming ready (exit ${n})`);await $(150)}throw new Error(`sootsim bridge did not start within ${Math.round(ze/1e3)}s`)}async function kt(){let e=Se();if(e&&D.existsSync(ve(e)))return;console.error(" installing sootsim engine runtime...");let{runRuntime:t}=await import("./runtime-NCWCN66Y.js");await t(["install"],{})}function It(e){let t=process.argv[1];return t&&D.existsSync(t)?je(process.execPath,[t,...e],{detached:!0,stdio:"ignore",env:process.env}):je("sootsim",e,{detached:!0,stdio:"ignore",env:process.env})}function z(e,t){return new Promise(o=>{let n=new pt(`ws://127.0.0.1:${e}`,{handshakeTimeout:t}),r=!1,s=i=>{if(!r){r=!0;try{n.close()}catch{}o(i)}};n.once("open",()=>s(!0)),n.once("error",()=>s(!1)),setTimeout(()=>s(!1),t)})}function ue(e){try{let t=new URL(e),o=t.pathname.replace(/\/+$/,"")||"/";return t.searchParams.has("open")||t.searchParams.has("port")||t.searchParams.has("bundle")||t.searchParams.has("demo")||t.pathname.includes("/sootsim/index.html")||o==="/sootsim"||t.pathname==="/__soot"||t.pathname==="/__soot/"||o==="/rn"||/^\/rn\/[^/]+$/i.test(o)||/^\/app\/[^/]+$/i.test(o)||o==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(o)||/^\/__soot\/app\/[^/]+$/i.test(o)}catch{return!1}}function Pt(e){try{let t=new URL(e,"http://sootsim.local");if(t.origin!=="http://sootsim.local")return!1;let o=t.pathname.replace(/\/+$/,"")||"/";return o==="/rn"||/^\/rn\/[^/]+$/i.test(o)||/^\/app\/[^/]+$/i.test(o)||o==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(o)||/^\/__soot\/app\/[^/]+$/i.test(o)}catch{return!1}}function Ct(e,t){let o=new URL(e,"http://sootsim.local"),n=new URL(t),r=V(n.pathname),s=o.pathname.startsWith("/__soot/")?o.pathname.slice(7):o.pathname;return n.pathname=`${r}${s}`,n.search=o.search,n.hash=o.hash,n.toString()}function Et(e){try{let t=new URL(e).pathname.replace(/\/+$/,"")||"/";return/^\/preview\/[^/]+$/.test(t)||/^\/build\/.+/.test(t)}catch{return!1}}async function Ro(e){let t=G(e);return(await Ye(t)).bundleUrl}function Mt(e){try{let t=new URL(e.startsWith("http")?e:`http://${e}`),o=t.pathname||"/";if(o!=="/"&&o!==""||t.search||t.hash||!/^(localhost|127\.0\.0\.1|\[::1\]|::1)$/i.test(t.hostname))return null;let n=t.port?Number(t.port):t.protocol==="https:"?443:80;return Number.isFinite(n)&&n>0?n:null}catch{return null}}async function Ye(e){let t=G(e),o=/^\d+$/.test(t)?Number(t):Mt(t);if(o&&o>0){let n=await ke(o);if(n)return{bundleUrl:n.bundleUrl,port:n.port,framework:n.framework,projectName:n.projectName}}return He(t)}function V(e){let t=e.replace(/\/+$/,"")||"/";return t==="/__soot"||t.startsWith("/__soot/")?"/__soot":""}function _t(e,t){let o=G(e),n=new URL(t),r=V(n.pathname);return n.pathname=`${r}/rn`,n.searchParams.delete("bundle"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.delete("open"),n.searchParams.delete("port"),/^\d+$/.test(o)?n.pathname=`${r}/rn/${o}`:(n.pathname=`${r}/rn`,n.searchParams.set("open",o)),n.toString()}function Ut(e){let t=G(e);return/^\d+$/.test(t)||/^https?:\/\//i.test(t)?!0:/^(localhost|127\.0\.0\.1|\[::1\]|[^/]+\.localhost):\d+(?:\/.*)?$/i.test(t)}async function Tt(e,t,o={}){let n=await Ye(e),r=new URL(t),s=V(r.pathname);r.pathname=`${s}/rn`,r.searchParams.delete("open"),r.searchParams.delete("port"),r.searchParams.delete("demo"),r.searchParams.delete("app");let i=o.hot===void 0?n.bundleUrl:xe(n.bundleUrl,o.hot);return r.searchParams.set("bundle",i),r.toString()}function Rt(e){return e.startsWith("~/")?M.join(ut.homedir(),e.slice(2)):M.isAbsolute(e)?e:M.resolve(process.cwd(),e)}function Ot(e){let t={},o={};for(let r=0;r<e.length;r++){if(e[r]==="--replace"){let s=e[r+1];s||(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let i=s.indexOf("=");(i<=0||i===s.length-1)&&(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let a=s.slice(0,i).trim(),l=Rt(s.slice(i+1).trim());D.existsSync(l)||(console.error(` sootsim open: replacement file not found: ${l}`),process.exit(1)),t[a]={file:l},r++;continue}if(e[r]==="--remap"){let s=e[r+1],i=s?s.indexOf("="):-1;(!s||i<=0||i===s.length-1)&&(console.error(" sootsim open: --remap expects <host:port>=<host:port>"),process.exit(1)),o[s.slice(0,i).trim()]=s.slice(i+1).trim(),r++;continue}}let n={};return Object.keys(t).length>0&&(n.modules=t),Object.keys(o).length>0&&(n.network={remap:o}),n.modules||n.network?n:void 0}function Ze(){return Re().shellBaseUrl}async function Bt(e){try{let t=new URL(e),o=t.searchParams.get("bundle")||"";if(!o)return e;let n=process.env.SOOT_REPO_DIR||await se(o)||void 0,r=Ce({bundleUrl:o,repoDir:n});if(r.length===0)return e;let s=await Dt(r);return s.length===0?e:(t.searchParams.set("appFonts",Ee(s)),t.toString())}catch{return e}}async function Dt(e){let t=await Promise.all(e.map(async n=>{let r=new AbortController,s=setTimeout(()=>r.abort(),1500);try{let i=await fetch(n.url,{method:"HEAD",signal:r.signal});return i.status>=200&&i.status<400?n:null}catch{return null}finally{clearTimeout(s)}})),o=[];for(let n of t)n!==null&&o.push(n);return o}async function Lt(e,t,o={}){if(!e)return new URL(t).toString();if(ue(e))return new URL(e).toString();if(Pt(e))return Ct(e,t);let n=gt[e.toLowerCase()];if(n){let r=new URL(t),s=V(r.pathname);return r.pathname=`${s}${n}`,r.toString()}return Ut(e)?Tt(e,t,o):_t(e,t)}async function At(e){try{let t=new URL(e),o=t.searchParams.get("bundle")||"";if(!o)return e;let n=process.env.SOOT_REPO_DIR||await se(o)||void 0,r=Me({bundleUrl:o,repoDir:n});return!r||r.imageUrl&&!await Nt(r.imageUrl)?e:(t.searchParams.set("appSplash",_e(r)),t.toString())}catch{return e}}async function Nt(e){let t=new AbortController,o=setTimeout(()=>t.abort(),1500);try{let n=await fetch(e,{method:"HEAD",signal:t.signal});return n.status>=200&&n.status<400}catch{return!1}finally{clearTimeout(o)}}async function q(e,t=Ze(),o={}){let n=await Lt(e,t,o),r=await At(await Bt(n));if(!o.device)return r;let s=new URL(r);return s.searchParams.set("device",o.device),s.toString()}function Ge(e,t){let o=e?.url||e?.origin||t;try{let n=new URL(o);return n.searchParams.delete("bundle"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.delete("open"),n.searchParams.delete("port"),n.searchParams.delete("inspectOpen"),n.searchParams.delete("appFonts"),n.searchParams.delete("appSplash"),n.toString()}catch{return t}}async function Ft(e,t,o,n={}){let r=new URL(await q(e,t,n));return r.searchParams.set("inspectOpen",o),r.toString()}async function Ht(e,t,o,n={}){let r=n.attempts??30,s=n.intervalMs??500,i=n.minNodeCount??10;for(let a=0;a<r;a++){let l=v(e,{commandTimeoutMs:t,simId:o,simIdSource:"flag"});try{let d=await l.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount()) || 0)()"});if(typeof d=="number"&&d>i)return{bridge:l,count:d}}catch{}l.close(),await $(s)}return null}function Wt(e){if(!e)return null;try{let t=new URL(e);if(t.searchParams.has("bundle")){let o=t.searchParams.get("bundle")||"";try{let n=new URL(o),r=n.pathname.length>36?`...${n.pathname.slice(-36)}`:n.pathname;return`bundle ${n.host}${r}`}catch{return"bundle"}}return t.searchParams.has("port")?`connect :${t.searchParams.get("port")||""}`:t.searchParams.has("open")?`connect ${t.searchParams.get("open")||""}`:t.searchParams.has("demo")?`demo ${t.searchParams.get("demo")||"default"}`:t.pathname.includes("/sootsim/index.html")||t.pathname==="/sootsim/"||t.pathname==="/sootsim"?"embedded sootsim":null}catch{return null}}function jt(e){let t=e.indexOf(":");if(t<=0)return e.length>24?`${e.slice(0,21)}\u2026`:e;let o=e.slice(0,t),n=e.slice(t+1),r=n.length>12?`${n.slice(0,8)}\u2026`:n;return o==="AGENTBUS_SESSION"||o==="CLAUDE_CODE_SESSION_ID"||o==="CODEX_THREAD_ID"?`agent ${r}`:`${o} ${r}`}function Oo(e,t){if(e.length===0){console.log(" no sims connected");return}console.log(` connected sims (${e.length}):
3
3
  `);for(let o of e){let n=o.lockedBy&&o.lockExpiresAt?`locked by ${jt(o.lockedBy)} (${Math.max(0,Math.round((o.lockExpiresAt-Date.now())/1e3))}s)`:"",r=[o.isPrimary?"primary":"",o.id===t?"selected":"",o.readyState,o.userVisible===!1?"hidden":o.userVisible===!0?"visible":"",o.attachedCliCount&&o.attachedCliCount>0?"in use":"",o.userFocused?"focused":"",n].filter(Boolean);console.log(` ${o.id}${r.length?` [${r.join(", ")}]`:""}`);let s=Wt(o.url);if(s)console.log(` loaded: ${s}`);else if(o.url){let a=o.url.length>96?`${o.url.slice(0,93)}\u2026`:o.url;console.log(` url: ${a}`)}else o.origin&&console.log(` origin: ${o.origin}`);let i=Kt(o);i&&console.log(` engine: ${i}`),o.title&&console.log(` title: ${o.title}`),o.visibilityState&&o.visibilityState!=="visible"&&console.log(` visibility: ${o.visibilityState}`),console.log(` connected: ${Ve(Date.now()-o.connectedAt)}`),o.lastActiveAt&&o.lastActiveAt>0&&console.log(` last active: ${Ve(Date.now()-o.lastActiveAt)}`)}}function Kt(e){let t=e.url||e.origin||"";if(!t)return null;try{let o=new URL(t).port;return o==="5173"?"dev \u2014 local source (:5173)":o==="3000"?"soot app embedded (:3000)":Pe()?`dev \u2014 local build (:${o||"?"})`:`runtime \u2014 published engine (:${o||"?"})`}catch{return null}}function Ve(e){let t=Math.max(0,Math.round(e/1e3));return t<60?`${t}s ago`:t<3600?`${Math.round(t/60)}m ago`:t<86400?`${Math.round(t/3600)}h ago`:`${Math.round(t/86400)}d ago`}async function de(e,t,o,n={}){let r=n.attempts??30,s=n.intervalMs??500;for(let i=0;i<r;i++){let a=v(e,{commandTimeoutMs:t});try{let d=(await a.listSims()).find(o);if(d)return d}catch{}finally{a.close()}await $(s)}return null}async function zt(e,t,o,n,r={}){let s=r.attempts??30,i=r.intervalMs??500,a=!!n&&Number.isInteger(n)&&n>1,l=()=>a&&n!==void 0&&!pe(n);for(let d=0;d<s;d++){if(l())return{kind:"host-exit"};let m=v(e,{commandTimeoutMs:t});try{let g=(await m.listSims()).find(o);if(g)return l()?{kind:"host-exit"}:{kind:"match",sim:g}}catch{}finally{m.close()}if(l())return{kind:"host-exit"};await $(i)}return{kind:"timeout"}}async function qt(e,t,o,n={}){let r=n.attempts??20,s=n.intervalMs??250;for(let i=0;i<r;i++){let a=v(e,{commandTimeoutMs:t});try{let d=(await a.listSims()).find(m=>m.id===o);if(!d||d.readyState!=="open")return!0}catch{return!0}finally{a.close()}await $(s)}return!1}function Gt(e){let t=e.meta;if(!t||t.sootsimHostDriver!=="playwright")return null;let o=Number(t.sootsimHostPid);return!Number.isInteger(o)||o<=1||o===process.pid?null:o}function Vt(e){if(!e.connectAckFile)return!1;try{return D.writeFileSync(e.connectAckFile,`${JSON.stringify({connectedAt:Date.now(),pid:e.pid??null})}
4
4
  `,{flag:"w"}),!0}catch{return!1}}function Je(e){if(e.diagnosticLogPath)try{let t=D.readFileSync(e.diagnosticLogPath,"utf8").trim();if(!t){console.error(` ${M.basename(e.diagnosticLogPath)} was empty`);return}let o=t.length>4e3?`\u2026
5
5
  ${t.slice(-4e3)}`:t;console.error(` ${M.basename(e.diagnosticLogPath)}:`),console.error(o)}catch(t){let o=t instanceof Error?t.message:String(t);console.error(` failed to read ${M.basename(e.diagnosticLogPath)}: ${o}`)}}function pe(e){try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function Jt(e,t=2500){let o=Date.now()+t;for(;Date.now()<o;){if(!pe(e))return!0;await $(100)}return!pe(e)}async function me(e,t){let o=new Set(t),n=new Set;for(let r of e){if(!o.has(r.id))continue;let s=Gt(r);s&&n.add(s)}for(let r of n){try{process.kill(r,"SIGTERM")}catch{}if(await Jt(r)){console.log(` closed playwright host process ${r}`);continue}try{process.kill(r,"SIGKILL"),console.log(` force-closed playwright host process ${r}`)}catch{}}}function J(e,t){if(t){let r=t.trim(),s=e.find(i=>i.id===r);if(!s)throw new Error(`no sim connected with id ${r}`);return s}let o=e.find(r=>r.isPrimary&&r.readyState==="open");if(o)return o;let n=e.find(r=>r.readyState==="open");if(n)return n;throw new Error("no sim connected")}function O(e,t,o){console.log(` ${o==="current sim"?"loaded":"opened"}: ${e} [${o}]`),console.log(` current sim: ${t.id}`),console.log(JSON.stringify({simId:t.id,url:t.url},null,2))}async function B(e,t,o){if(o.includes("--no-describe"))return;let n=process.env.SOOTSIM_QUIET_TARGET_NOTICE;process.env.SOOTSIM_QUIET_TARGET_NOTICE="1";try{await Qt(e,t,{stableMs:150,maxMs:400});let r=v(e,{commandTimeoutMs:3e3,simId:t,cliLabel:"open --describe",simIdSource:"flag"});try{let s=null;try{s=await r.send({type:"evaluate",code:Ue})}catch{}if(s&&!(s.flag===!0&&!s.loadingText&&Te(s))){let m=s.loadingText?`still showing "${s.loadingText}"`:s.flag!==!0?"guest ready event has not fired":s.targets<=0?"no visible app content is inspectable yet":"app tree is still stabilizing";console.log(` app still loading: ${m} (nodes: ${s.nodes}, targets: ${s.targets})`),console.log(" before interacting, run: sootsim wait ready --max-ms 120000")}let a=`(async () => {
@@ -10,4 +10,4 @@ ${t.slice(-4e3)}`:t;console.error(` ${M.basename(e.diagnosticLogPath)}:`),conso
10
10
  try { shell = ms?.getState ? await ms.getState() : null } catch {}
11
11
  const tree = await t.dumpTree(12, ${JSON.stringify({describe:!0,verbose:!1,filter:""})})
12
12
  return { tree, shell }
13
- })()`,l=await r.send({type:"evaluate",code:a});if(!l?.tree)return;if(console.log(""),l.shell?.state){let d=[`state=${l.shell.state}`,l.shell.activeApp?`app=${l.shell.activeApp}`:null].filter(Boolean);console.log(` shell: ${d.join(" ")}`)}console.log(l.tree)}finally{r.close()}}catch{}finally{n===void 0?delete process.env.SOOTSIM_QUIET_TARGET_NOTICE:process.env.SOOTSIM_QUIET_TARGET_NOTICE=n}}async function Qt(e,t,o){let n=Date.now()+o.maxMs,r="(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()",s=v(e,{commandTimeoutMs:2e3,simId:t,simIdSource:"flag"});try{let i=-1,a=0;for(;Date.now()<n;){let l=-1;try{let d=await s.send({type:"evaluate",code:r});typeof d=="number"&&(l=d)}catch{}if(l>=0&&l===i){if(Date.now()-a>=o.stableMs)return}else i=l,a=Date.now();await $(50)}}finally{s.close()}}async function Yt(e,t={}){let o=C(e,{port:t.port,commandTimeoutMs:t.timeoutMs});o.positional.length!==1&&(console.error(" sootsim open: expected exactly one <url-or-route>"),console.error(" examples: sootsim open /settings | sootsim open myapp://settings"),process.exit(1));let n;try{n=vt(o.positional[0]??"")}catch(i){console.error(` sootsim open: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}let r=E(o),s=o.simId?` --sim ${o.simId}`:"";try{let i=await r.send({type:"call",path:"SootSim.bridges.test.openDeepLink",args:[n]});if(St(i)&&i.ok===!1)throw new Error(typeof i.error=="string"?i.error:"deep-link dispatch failed");console.log(` opened deep link: ${n}`)}catch(i){console.error(` link failed: ${i instanceof Error?i.message:String(i)}`),await T(r,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}finally{r.close()}}async function Bo(e,t={}){let o=C(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--new","--headless","--headed","--ephemeral","--hot","--no-hmr","--no-describe"],stripValueFlags:["--base-url","--replace","--driver","--profile","--cdp-port","--browser","--device"]}),n=e.find((c,p)=>e[p-1]==="--profile"),r=e.includes("--ephemeral"),s=e.find((c,p)=>e[p-1]==="--cdp-port"),i=s?Number(s):void 0;s&&(!Number.isFinite(i)||i<=0)&&(console.error(` sootsim open: --cdp-port must be a positive port number, got "${s}"`),process.exit(1)),n&&r&&(console.error(" sootsim open: --profile cannot be combined with --ephemeral"),process.exit(1));let a=n?Ie(n).id:void 0,l=!!a||r,d=e.includes("--new")||l,m=Ot(e);d&&o.simIdSource==="flag"&&(console.error(" sootsim open: --new, --profile, and --ephemeral cannot be combined with --sim"),process.exit(1));let u=o.positional[0]||"";if($t(u)){d&&(console.error(" sootsim open: deep links target the current app; remove --new, --profile, or --ephemeral"),process.exit(1)),await Yt(e,t);return}if(Et(u)){let c=(()=>{try{return/^(localhost|127\.0\.0\.1|\[::1\]|::1)$/i.test(new URL(u).hostname)}catch{return!1}})();console.log(" that\u2019s a SootSim preview/build link \u2014 a full player page, not a driveable sim."),console.log(" opening it in your browser for viewing\u2026");try{await le(u,{background:!1})}catch(p){console.error(` could not launch a browser: ${p instanceof Error?p.message:String(p)}`),console.error(` open it yourself: ${u}`),process.exit(1)}console.log(c?" to drive it under the CLI, point `sootsim open` at the app\u2019s dev port instead (e.g. `sootsim open 8081`).":" the CLI can\u2019t drive a remote preview (the engine only attaches to the local bridge from localhost). to drive the app, run it locally and `sootsim open <port>`.");return}let g=e.find((c,p)=>e[p-1]==="--base-url"),Q=t.port!==void 0||e.some(c=>c==="--port"||c==="-p"||c.startsWith("--port="));if(g&&!Q){let c=ie(g);c&&(o.wsPort=c)}o.wsPort=await xt(o.wsPort);let y=e.find((c,p)=>e[p-1]==="--driver")||"",et=yt(e,y);i&&y!=="playwright"&&(console.error(" sootsim open: --cdp-port is only honored by the playwright driver \u2014 add `--driver playwright`"),process.exit(1));let x=e.find((c,p)=>e[p-1]==="--browser");x&&y!=="playwright"&&(console.error(" sootsim open: --browser is only honored by the playwright driver \u2014 add `--driver playwright`"),process.exit(1));let L=x==="chromium"||x==="webkit"||x==="firefox"?x:void 0;x&&!L&&(console.error(` sootsim open: --browser must be chromium, webkit, or firefox \u2014 got "${x}"`),process.exit(1)),i&&L&&L!=="chromium"&&(console.error(" sootsim open: --cdp-port requires the chromium engine"),process.exit(1));let fe=e.includes("--hot"),he=e.includes("--no-hmr");fe&&he&&(console.error(" sootsim open: --hot and --no-hmr cannot be combined"),process.exit(1));let tt=fe?!0:he?!1:y!=="playwright",k=e.find((c,p)=>e[p-1]==="--device");k&&!(k in oe)&&(console.error(` sootsim open: unknown device "${k}"`),console.error(` known devices: ${$e().join(", ")}`),process.exit(1));let Y=k?oe[k]:void 0,A={hot:tt,device:k},ot=Oe(o.wsPort),I=g||ot?.shellBaseUrl||Ze(),ge=e.includes("--base-url");Be(o.wsPort,I);let we=_();if(!y&&!d&&(o.simIdSource==="flag"||o.simIdSource==="saved"&&!!we)){let c=E(o),p=o.simId?` --sim ${o.simId}`:"",f=!1;try{let h=null;try{let w=await c.listSims();if(o.simIdSource==="saved"?(h=w.find(P=>P.id===we&&P.readyState==="open")??null,h||U()):h=J(w,o.simId),!h)if(o.simIdSource==="saved")f=!0;else throw new Error("no sim connected");if(!f&&h){let P=ge||ue(u)?I:Ge(h,I),H=await q(u,j(P,m),A);c.send({type:"evaluate",simId:h.id,code:`window.location.href = ${JSON.stringify(H)}`}).catch(()=>{})}}catch(w){console.error(` open failed: ${w instanceof Error?w.message:String(w)}`),await T(c,{errorsCommand:`sootsim get errors 5${p}`,warningsCommand:`sootsim get warnings 5${p}`,requestsCommand:`sootsim get requests 5${p}`}),process.exit(1)}if(!f&&h){await $(1500);let w=await Ht(o.wsPort,o.commandTimeoutMs,h.id);w||(console.error(" timed out waiting for current sim to load target"),process.exit(1)),w.bridge.close(),b(h.id);let P=ge||ue(u)?I:Ge(h,I),H=await q(u,j(P,m),A);O(H,{...h,url:H},"current sim"),await B(o.wsPort,h.id,e);return}}finally{c.close()}}let be=j(I,m),nt=await q(u,be,A),ye=`cli-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,S=await Ft(u,be,ye,A),Z={newWindow:!0},N=c=>c.url?.includes(`inspectOpen=${ye}`)??!1;if(y){bt(y)||(console.error(` unknown driver "${y}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let c=ce(y);c||(console.error(` unknown driver "${y}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let p=wt(),f=await c.launch({url:S,bridgePort:ie(I)??void 0,headless:et,newWindow:Z.newWindow,profileId:a,ephemeralProfile:r,cdpPort:i,browser:L,device:k,viewport:Y?{width:Y.width+120,height:Y.height+60}:void 0,connectTimeoutMs:p.hostTimeoutMs});f.launched||(console.error(` ${c.name} driver: ${f.message}`),process.exit(1));let h=await zt(o.wsPort,o.commandTimeoutMs,N,f.pid,{attempts:p.attempts,intervalMs:p.intervalMs});if(h.kind==="host-exit"&&(Je(f),console.error(` ${c.name} host crashed \u2014 sim is no longer attached`),process.exit(1)),h.kind==="timeout"){if(f.pid)try{process.kill(f.pid,"SIGTERM"),console.error(` closed ${c.name} host process ${f.pid}`)}catch{}Je(f),console.error(` timed out after ${p.timeoutMs}ms waiting for opened sim to connect`),process.exit(1)}let w=h.sim;b(w.id),Vt(f),O(S,w,`${c.name} driver`),await B(o.wsPort,w.id,e);return}if(l){let c=R();c||(console.error(" profiles require electron or playwright; install the desktop companion or use `--driver playwright`"),process.exit(1));try{(await ae(S,c,{profileId:a,ephemeralProfile:r})).launched||(console.error(" desktop companion failed to start"),process.exit(1))}catch(f){console.error(` desktop companion failed: ${f instanceof Error?f.message:String(f)}`),process.exit(1)}let p=await de(o.wsPort,o.commandTimeoutMs,N,{attempts:40,intervalMs:500});p||(console.error(" timed out waiting for profiled sim to connect"),process.exit(1)),b(p.id),O(S,p,"desktop companion"),await B(o.wsPort,p.id,e);return}let X=!1,ee=!1;try{let c=v(o.wsPort,{commandTimeoutMs:2e3});try{await c.listSims(),X=!0}finally{c.close()}}catch{}if(X)try{let c=v(o.wsPort,{commandTimeoutMs:3e3});try{await c.openUrl(S,Z),ee=!0}finally{c.close()}}catch{}if(!ee){let c=R();if(c)try{if((await ae(S,c)).launched){let f=await de(o.wsPort,o.commandTimeoutMs,N,{attempts:20,intervalMs:500});if(f){b(f.id),O(S,f,"desktop companion"),await B(o.wsPort,f.id,e);return}}}catch{}try{await le(S,Z)}catch(p){console.error(` open failed: ${p instanceof Error?p.message:String(p)}`),ce("playwright")?.availability().available?console.error(" no system browser found \u2014 retry with `sootsim open \u2026 --driver playwright` for a headless sim."):console.error(" run `sootsim list --drivers` to see available drivers."),process.exit(1)}if(!X){console.log(` opened: ${nt}`),We(o.wsPort);return}}let F=await de(o.wsPort,o.commandTimeoutMs,N,{attempts:30,intervalMs:500});F||(console.error(" timed out waiting for opened sim to connect"),process.exit(1)),b(F.id),O(S,F,ee?"bridge":"direct shell open"),await B(o.wsPort,F.id,e)}async function Xe(e,t={}){let o=C(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=E(o),s=o.simId?` --sim ${o.simId}`:"";try{try{let i=await r.listSims(),a=J(i,o.positional[0]||o.simId);if(a.lockedBy&&a.lockExpiresAt&&a.lockExpiresAt>Date.now()){let l=Math.max(0,Math.round((a.lockExpiresAt-Date.now())/1e3));a.lockedByKind==="user-active"&&(console.error(` refused: ${a.id} is locked by the active user (${l}s) \u2014 that's a live human tab`),console.error(" run `sootsim open --new` for a fresh investigation sim"),process.exit(1)),n||(console.error(` refused: ${a.id} is leased by ${a.lockedBy} (${l}s)`),console.error(` \`sootsim use ${a.id} --force\` to take it, or \`sootsim open --new\` for a fresh sim`),process.exit(1))}await r.focusSim(a.id),b(a.id),console.log(` using: ${a.id}`)}catch(i){console.error(` use failed: ${i instanceof Error?i.message:String(i)}`),await T(r,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}}finally{r.close()}}async function Do(e,t={}){await Xe(e,t)}async function Lo(e,t={}){await Xe(e,t)}async function Ao(e,t={}){let o=C(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=E(o);try{try{let s=await r.listSims(),i=J(s,o.positional[0]||o.simId),a=n&&i.lockedBy&&i.lockedByKind!=="user-active"?i.lockedBy:null,l=await r.claim(i.id,{force:n});b(i.id);let d=Math.max(0,Math.round((l.lockExpiresAt-Date.now())/1e3)),m=l.bootedCount>0?` (booted ${l.bootedCount})`:"";console.log(` claimed: ${l.simId} [${d}s]${m}`),a&&console.log(` took over from: ${a}`)}catch(s){if(s instanceof De){let i=Math.max(0,Math.round(s.lock.expiresInMs/1e3));console.error(` claim failed: locked by ${s.lock.by} for ${i}s more`),console.error(" use --force to take it, or `sootsim open --new` for a fresh sim"),process.exit(1)}console.error(` claim failed: ${s instanceof Error?s.message:String(s)}`),process.exit(1)}}finally{r.close()}}async function Zt(e,t,o,n){if(n.length===0)return{closed:[],remaining:[]};await Promise.all(n.map(s=>e.closeSim(s).catch(()=>{})));let r=new Set(n);for(let s=0;s<40;s++){let i=[];try{let a=v(t,{commandTimeoutMs:o});try{i=(await a.listSims()).filter(d=>r.has(d.id)&&d.readyState==="open").map(d=>d.id)}finally{a.close()}}catch{i=[]}if(i.length===0)return{closed:[...r],remaining:[]};if(s===39)return{closed:[...r].filter(a=>!i.includes(a)),remaining:i};await $(250)}return{closed:[...r],remaining:[]}}function Xt(e,t){let o=e.filter(u=>u.readyState==="open"),n=o.map(u=>u.id),r=t.explicitKeepId?.trim()||"",s=t.savedKeepId?.trim()||"",i=s?o.some(u=>u.id===s):!1,a=s&&!i?s:null,l=null,d=null,m=null;if(t.closeOthers)if(r){let u=o.find(g=>g.id===r);u?l=u.id:d=r}else if(s&&i)l=s;else{let u=o.find(g=>g.isPrimary)??o[0]??null;u&&(l=u.id,s&&!i&&(m=u.id))}return{openIds:n,keepId:l,targets:d?[]:n.filter(u=>u!==l),staleSavedId:a,missingExplicitKeepId:d,fallbackKeepId:m}}async function No(e,t={}){let o=C(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--all","--others"]}),n=E(o),r=o.simId?` --sim ${o.simId}`:"",s=e.includes("--all"),i=e.includes("--others");if(s||i){try{let a=await n.listSims(),l=_(),d=o.positional[0]||(o.simIdSource==="flag"?o.simId:void 0),m=Xt(a,{closeOthers:i,explicitKeepId:d,savedKeepId:l});if(m.staleSavedId&&U(),m.fallbackKeepId&&(b(m.fallbackKeepId),console.log(` saved sim ${m.staleSavedId} is gone \u2014 keeping primary ${m.fallbackKeepId}`)),m.missingExplicitKeepId&&(console.error(` close failed: keep sim ${m.missingExplicitKeepId} is not connected; not closing other sims`),process.exit(1)),m.targets.length===0){console.log(m.keepId?` nothing to close \u2014 only the kept sim ${m.keepId} is connected`:m.staleSavedId?` nothing to close \u2014 no sims connected (cleared stale current sim ${m.staleSavedId})`:" nothing to close \u2014 no sims connected");return}let u=await Zt(n,o.wsPort,o.commandTimeoutMs,m.targets);await me(a,m.targets);let g=_();g&&u.closed.includes(g)&&(m.keepId?b(m.keepId):U());let Q=` closed ${u.closed.length} sim(s)${m.keepId?` (kept ${m.keepId})`:""}`;console.log(Q),u.remaining.length>0&&(console.error(` close failed: still connected: ${u.remaining.join(", ")}`),process.exit(1))}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),process.exit(1)}finally{n.close()}return}try{try{let a=await n.listSims(),l=J(a,o.positional[0]||o.simId),d=a.find(u=>u.id!==l.id&&u.readyState==="open");await n.closeSim(l.id),await qt(o.wsPort,o.commandTimeoutMs,l.id)||(await me(a,[l.id]),console.error(` close failed: ${l.id} is still connected`),process.exit(1)),await me(a,[l.id]),_()===l.id&&(d?b(d.id):U()),console.log(` closed: ${l.id}`)}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),await T(n,{errorsCommand:`sootsim get errors 5${r}`,warningsCommand:`sootsim get warnings 5${r}`,requestsCommand:`sootsim get requests 5${r}`}),process.exit(1)}}finally{n.close()}}export{io as a,mt as b,ao as c,wt as d,vt as e,Ro as f,Ze as g,q as h,Ft as i,Wt as j,Oo as k,de as l,zt as m,Gt as n,Vt as o,me as p,Yt as q,Bo as r,Do as s,Lo as t,Ao as u,Zt as v,Xt as w,No as x};
13
+ })()`,l=await r.send({type:"evaluate",code:a});if(!l?.tree)return;if(console.log(""),l.shell?.state){let d=[`state=${l.shell.state}`,l.shell.activeApp?`app=${l.shell.activeApp}`:null].filter(Boolean);console.log(` shell: ${d.join(" ")}`)}console.log(l.tree)}finally{r.close()}}catch{}finally{n===void 0?delete process.env.SOOTSIM_QUIET_TARGET_NOTICE:process.env.SOOTSIM_QUIET_TARGET_NOTICE=n}}async function Qt(e,t,o){let n=Date.now()+o.maxMs,r="(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()",s=v(e,{commandTimeoutMs:2e3,simId:t,simIdSource:"flag"});try{let i=-1,a=0;for(;Date.now()<n;){let l=-1;try{let d=await s.send({type:"evaluate",code:r});typeof d=="number"&&(l=d)}catch{}if(l>=0&&l===i){if(Date.now()-a>=o.stableMs)return}else i=l,a=Date.now();await $(50)}}finally{s.close()}}async function Yt(e,t={}){let o=C(e,{port:t.port,commandTimeoutMs:t.timeoutMs});o.positional.length!==1&&(console.error(" sootsim open: expected exactly one <url-or-route>"),console.error(" examples: sootsim open /settings | sootsim open myapp://settings"),process.exit(1));let n;try{n=vt(o.positional[0]??"")}catch(i){console.error(` sootsim open: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}let r=E(o),s=o.simId?` --sim ${o.simId}`:"";try{let i=await r.send({type:"call",path:"SootSim.bridges.test.openDeepLink",args:[n]});if(St(i)&&i.ok===!1)throw new Error(typeof i.error=="string"?i.error:"deep-link dispatch failed");console.log(` opened deep link: ${n}`)}catch(i){console.error(` link failed: ${i instanceof Error?i.message:String(i)}`),await T(r,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}finally{r.close()}}async function Bo(e,t={}){let o=C(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--new","--headless","--headed","--ephemeral","--hot","--no-hmr","--no-describe"],stripValueFlags:["--base-url","--replace","--driver","--profile","--cdp-port","--browser","--device"]}),n=e.find((c,p)=>e[p-1]==="--profile"),r=e.includes("--ephemeral"),s=e.find((c,p)=>e[p-1]==="--cdp-port"),i=s?Number(s):void 0;s&&(!Number.isFinite(i)||i<=0)&&(console.error(` sootsim open: --cdp-port must be a positive port number, got "${s}"`),process.exit(1)),n&&r&&(console.error(" sootsim open: --profile cannot be combined with --ephemeral"),process.exit(1));let a=n?Ie(n).id:void 0,l=!!a||r,d=e.includes("--new")||l,m=Ot(e);d&&o.simIdSource==="flag"&&(console.error(" sootsim open: --new, --profile, and --ephemeral cannot be combined with --sim"),process.exit(1));let u=o.positional[0]||"";if($t(u)){d&&(console.error(" sootsim open: deep links target the current app; remove --new, --profile, or --ephemeral"),process.exit(1)),await Yt(e,t);return}if(Et(u)){let c=(()=>{try{return/^(localhost|127\.0\.0\.1|\[::1\]|::1)$/i.test(new URL(u).hostname)}catch{return!1}})();console.log(" that\u2019s a SootSim preview/build link \u2014 a full player page, not a driveable sim."),console.log(" opening it in your browser for viewing\u2026");try{await le(u,{background:!1})}catch(p){console.error(` could not launch a browser: ${p instanceof Error?p.message:String(p)}`),console.error(` open it yourself: ${u}`),process.exit(1)}console.log(c?" to drive it under the CLI, point `sootsim open` at the app\u2019s dev port instead (e.g. `sootsim open 8081`).":" the CLI can\u2019t drive a remote preview (the engine only attaches to the local bridge from localhost). to drive the app, run it locally and `sootsim open <port>`.");return}let g=e.find((c,p)=>e[p-1]==="--base-url"),Q=t.port!==void 0||e.some(c=>c==="--port"||c==="-p"||c.startsWith("--port="));if(g&&!Q){let c=ie(g);c&&(o.wsPort=c)}o.wsPort=await xt(o.wsPort);let y=e.find((c,p)=>e[p-1]==="--driver")||"",et=yt(e,y);i&&y!=="playwright"&&(console.error(" sootsim open: --cdp-port is only honored by the playwright driver \u2014 add `--driver playwright`"),process.exit(1));let x=e.find((c,p)=>e[p-1]==="--browser");x&&y!=="playwright"&&(console.error(" sootsim open: --browser is only honored by the playwright driver \u2014 add `--driver playwright`"),process.exit(1));let L=x==="chromium"||x==="webkit"||x==="firefox"?x:void 0;x&&!L&&(console.error(` sootsim open: --browser must be chromium, webkit, or firefox \u2014 got "${x}"`),process.exit(1)),i&&L&&L!=="chromium"&&(console.error(" sootsim open: --cdp-port requires the chromium engine"),process.exit(1));let fe=e.includes("--hot"),he=e.includes("--no-hmr");fe&&he&&(console.error(" sootsim open: --hot and --no-hmr cannot be combined"),process.exit(1));let tt=fe?!0:he?!1:y!=="playwright",k=e.find((c,p)=>e[p-1]==="--device");k&&!(k in oe)&&(console.error(` sootsim open: unknown device "${k}"`),console.error(` known devices: ${$e().join(", ")}`),process.exit(1));let Y=k?oe[k]:void 0,A={hot:tt,device:k},ot=Oe(o.wsPort),I=g||ot?.shellBaseUrl||Ze(),ge=e.includes("--base-url");Be(o.wsPort,I);let we=_();if(!y&&!d&&(o.simIdSource==="flag"||o.simIdSource==="saved"&&!!we)){let c=E(o),p=o.simId?` --sim ${o.simId}`:"",f=!1;try{let h=null;try{let w=await c.listSims();if(o.simIdSource==="saved"?(h=w.find(P=>P.id===we&&P.readyState==="open")??null,h||U()):h=J(w,o.simId),!h)if(o.simIdSource==="saved")f=!0;else throw new Error("no sim connected");if(!f&&h){let P=ge||ue(u)?I:Ge(h,I),H=await q(u,j(P,m),A);c.send({type:"evaluate",simId:h.id,code:`window.location.href = ${JSON.stringify(H)}`}).catch(()=>{})}}catch(w){console.error(` open failed: ${w instanceof Error?w.message:String(w)}`),await T(c,{errorsCommand:`sootsim get errors 5${p}`,warningsCommand:`sootsim get warnings 5${p}`,requestsCommand:`sootsim get requests 5${p}`}),process.exit(1)}if(!f&&h){await $(1500);let w=await Ht(o.wsPort,o.commandTimeoutMs,h.id);w||(console.error(" timed out waiting for current sim to load target"),process.exit(1)),w.bridge.close(),b(h.id);let P=ge||ue(u)?I:Ge(h,I),H=await q(u,j(P,m),A);O(H,{...h,url:H},"current sim"),await B(o.wsPort,h.id,e);return}}finally{c.close()}}let be=j(I,m),nt=await q(u,be,A),ye=`cli-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,S=await Ft(u,be,ye,A),Z={newWindow:!0},N=c=>c.url?.includes(`inspectOpen=${ye}`)??!1;if(y){bt(y)||(console.error(` unknown driver "${y}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let c=ce(y);c||(console.error(` unknown driver "${y}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let p=wt(),f=await c.launch({url:S,bridgePort:ie(I)??o.wsPort,headless:et,newWindow:Z.newWindow,profileId:a,ephemeralProfile:r,cdpPort:i,browser:L,device:k,viewport:Y?{width:Y.width+120,height:Y.height+60}:void 0,connectTimeoutMs:p.hostTimeoutMs});f.launched||(console.error(` ${c.name} driver: ${f.message}`),process.exit(1));let h=await zt(o.wsPort,o.commandTimeoutMs,N,f.pid,{attempts:p.attempts,intervalMs:p.intervalMs});if(h.kind==="host-exit"&&(Je(f),console.error(` ${c.name} host crashed \u2014 sim is no longer attached`),process.exit(1)),h.kind==="timeout"){if(f.pid)try{process.kill(f.pid,"SIGTERM"),console.error(` closed ${c.name} host process ${f.pid}`)}catch{}Je(f),console.error(` timed out after ${p.timeoutMs}ms waiting for opened sim to connect`),process.exit(1)}let w=h.sim;b(w.id),Vt(f),O(S,w,`${c.name} driver`),await B(o.wsPort,w.id,e);return}if(l){let c=R();c||(console.error(" profiles require electron or playwright; install the desktop companion or use `--driver playwright`"),process.exit(1));try{(await ae(S,c,{profileId:a,ephemeralProfile:r})).launched||(console.error(" desktop companion failed to start"),process.exit(1))}catch(f){console.error(` desktop companion failed: ${f instanceof Error?f.message:String(f)}`),process.exit(1)}let p=await de(o.wsPort,o.commandTimeoutMs,N,{attempts:40,intervalMs:500});p||(console.error(" timed out waiting for profiled sim to connect"),process.exit(1)),b(p.id),O(S,p,"desktop companion"),await B(o.wsPort,p.id,e);return}let X=!1,ee=!1;try{let c=v(o.wsPort,{commandTimeoutMs:2e3});try{await c.listSims(),X=!0}finally{c.close()}}catch{}if(X)try{let c=v(o.wsPort,{commandTimeoutMs:3e3});try{await c.openUrl(S,Z),ee=!0}finally{c.close()}}catch{}if(!ee){let c=R();if(c)try{if((await ae(S,c)).launched){let f=await de(o.wsPort,o.commandTimeoutMs,N,{attempts:20,intervalMs:500});if(f){b(f.id),O(S,f,"desktop companion"),await B(o.wsPort,f.id,e);return}}}catch{}try{await le(S,Z)}catch(p){console.error(` open failed: ${p instanceof Error?p.message:String(p)}`),ce("playwright")?.availability().available?console.error(" no system browser found \u2014 retry with `sootsim open \u2026 --driver playwright` for a headless sim."):console.error(" run `sootsim list --drivers` to see available drivers."),process.exit(1)}if(!X){console.log(` opened: ${nt}`),We(o.wsPort);return}}let F=await de(o.wsPort,o.commandTimeoutMs,N,{attempts:30,intervalMs:500});F||(console.error(" timed out waiting for opened sim to connect"),process.exit(1)),b(F.id),O(S,F,ee?"bridge":"direct shell open"),await B(o.wsPort,F.id,e)}async function Xe(e,t={}){let o=C(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=E(o),s=o.simId?` --sim ${o.simId}`:"";try{try{let i=await r.listSims(),a=J(i,o.positional[0]||o.simId);if(a.lockedBy&&a.lockExpiresAt&&a.lockExpiresAt>Date.now()){let l=Math.max(0,Math.round((a.lockExpiresAt-Date.now())/1e3));a.lockedByKind==="user-active"&&(console.error(` refused: ${a.id} is locked by the active user (${l}s) \u2014 that's a live human tab`),console.error(" run `sootsim open --new` for a fresh investigation sim"),process.exit(1)),n||(console.error(` refused: ${a.id} is leased by ${a.lockedBy} (${l}s)`),console.error(` \`sootsim use ${a.id} --force\` to take it, or \`sootsim open --new\` for a fresh sim`),process.exit(1))}await r.focusSim(a.id),b(a.id),console.log(` using: ${a.id}`)}catch(i){console.error(` use failed: ${i instanceof Error?i.message:String(i)}`),await T(r,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}}finally{r.close()}}async function Do(e,t={}){await Xe(e,t)}async function Lo(e,t={}){await Xe(e,t)}async function Ao(e,t={}){let o=C(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=E(o);try{try{let s=await r.listSims(),i=J(s,o.positional[0]||o.simId),a=n&&i.lockedBy&&i.lockedByKind!=="user-active"?i.lockedBy:null,l=await r.claim(i.id,{force:n});b(i.id);let d=Math.max(0,Math.round((l.lockExpiresAt-Date.now())/1e3)),m=l.bootedCount>0?` (booted ${l.bootedCount})`:"";console.log(` claimed: ${l.simId} [${d}s]${m}`),a&&console.log(` took over from: ${a}`)}catch(s){if(s instanceof De){let i=Math.max(0,Math.round(s.lock.expiresInMs/1e3));console.error(` claim failed: locked by ${s.lock.by} for ${i}s more`),console.error(" use --force to take it, or `sootsim open --new` for a fresh sim"),process.exit(1)}console.error(` claim failed: ${s instanceof Error?s.message:String(s)}`),process.exit(1)}}finally{r.close()}}async function Zt(e,t,o,n){if(n.length===0)return{closed:[],remaining:[]};await Promise.all(n.map(s=>e.closeSim(s).catch(()=>{})));let r=new Set(n);for(let s=0;s<40;s++){let i=[];try{let a=v(t,{commandTimeoutMs:o});try{i=(await a.listSims()).filter(d=>r.has(d.id)&&d.readyState==="open").map(d=>d.id)}finally{a.close()}}catch{i=[]}if(i.length===0)return{closed:[...r],remaining:[]};if(s===39)return{closed:[...r].filter(a=>!i.includes(a)),remaining:i};await $(250)}return{closed:[...r],remaining:[]}}function Xt(e,t){let o=e.filter(u=>u.readyState==="open"),n=o.map(u=>u.id),r=t.explicitKeepId?.trim()||"",s=t.savedKeepId?.trim()||"",i=s?o.some(u=>u.id===s):!1,a=s&&!i?s:null,l=null,d=null,m=null;if(t.closeOthers)if(r){let u=o.find(g=>g.id===r);u?l=u.id:d=r}else if(s&&i)l=s;else{let u=o.find(g=>g.isPrimary)??o[0]??null;u&&(l=u.id,s&&!i&&(m=u.id))}return{openIds:n,keepId:l,targets:d?[]:n.filter(u=>u!==l),staleSavedId:a,missingExplicitKeepId:d,fallbackKeepId:m}}async function No(e,t={}){let o=C(e,{port:t.port,commandTimeoutMs:t.timeoutMs,stripBooleanFlags:["--all","--others"]}),n=E(o),r=o.simId?` --sim ${o.simId}`:"",s=e.includes("--all"),i=e.includes("--others");if(s||i){try{let a=await n.listSims(),l=_(),d=o.positional[0]||(o.simIdSource==="flag"?o.simId:void 0),m=Xt(a,{closeOthers:i,explicitKeepId:d,savedKeepId:l});if(m.staleSavedId&&U(),m.fallbackKeepId&&(b(m.fallbackKeepId),console.log(` saved sim ${m.staleSavedId} is gone \u2014 keeping primary ${m.fallbackKeepId}`)),m.missingExplicitKeepId&&(console.error(` close failed: keep sim ${m.missingExplicitKeepId} is not connected; not closing other sims`),process.exit(1)),m.targets.length===0){console.log(m.keepId?` nothing to close \u2014 only the kept sim ${m.keepId} is connected`:m.staleSavedId?` nothing to close \u2014 no sims connected (cleared stale current sim ${m.staleSavedId})`:" nothing to close \u2014 no sims connected");return}let u=await Zt(n,o.wsPort,o.commandTimeoutMs,m.targets);await me(a,m.targets);let g=_();g&&u.closed.includes(g)&&(m.keepId?b(m.keepId):U());let Q=` closed ${u.closed.length} sim(s)${m.keepId?` (kept ${m.keepId})`:""}`;console.log(Q),u.remaining.length>0&&(console.error(` close failed: still connected: ${u.remaining.join(", ")}`),process.exit(1))}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),process.exit(1)}finally{n.close()}return}try{try{let a=await n.listSims(),l=J(a,o.positional[0]||o.simId),d=a.find(u=>u.id!==l.id&&u.readyState==="open");await n.closeSim(l.id),await qt(o.wsPort,o.commandTimeoutMs,l.id)||(await me(a,[l.id]),console.error(` close failed: ${l.id} is still connected`),process.exit(1)),await me(a,[l.id]),_()===l.id&&(d?b(d.id):U()),console.log(` closed: ${l.id}`)}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),await T(n,{errorsCommand:`sootsim get errors 5${r}`,warningsCommand:`sootsim get warnings 5${r}`,requestsCommand:`sootsim get requests 5${r}`}),process.exit(1)}}finally{n.close()}}export{io as a,mt as b,ao as c,wt as d,vt as e,Ro as f,Ze as g,q as h,Ft as i,Wt as j,Oo as k,de as l,zt as m,Gt as n,Vt as o,me as p,Yt as q,Bo as r,Do as s,Lo as t,Ao as u,Zt as v,Xt as w,No as x};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{c as f}from"./chunk-5FQMI3PB.js";import{a as C,d as W,f as x}from"./chunk-DWL4WFZ2.js";import{M as y,N as w,O as I,P as S}from"./chunk-ERG3QCK4.js";import{WebSocket as v}from"ws";function L(){let i=w();if(i&&S(i))return{source:"dev-bridge",bridgePort:i.bridgePort,shellBaseUrl:i.shellPort?`http://localhost:${i.shellPort}/`:f};let r=y();return r&&I(r)?{source:"daemon",bridgePort:r.bridgePort,shellBaseUrl:r.runtimePort>0?`http://localhost:${r.runtimePort}/`:f}:{source:"default",bridgePort:7668,shellBaseUrl:f}}function E(i){let r=w();if(r&&S(r)&&r.bridgePort===i)return{source:"dev-bridge",shellBaseUrl:r.shellPort?`http://localhost:${r.shellPort}/`:f};let e=y();return e&&I(e)&&e.bridgePort===i?{source:"daemon",shellBaseUrl:e.runtimePort>0?`http://localhost:${e.runtimePort}/`:f}:null}function q(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=w();if(e&&S(e)&&(e.shellPort===r||e.runtimePort===r||e.bridgePort===r))return e.bridgePort;let d=y();return d&&I(d)&&(d.runtimePort===r||d.bridgePort===r)?d.bridgePort:null}function O(){return L().bridgePort}function H(i,r){let e=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.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{c as f}from"./chunk-BNUZWRON.js";import{a as C,d as W,f as x}from"./chunk-KPRSDBWU.js";import{M as y,N as w,O as I,P as S}from"./chunk-TX53NA5W.js";import{WebSocket as v}from"ws";function L(){let i=w();if(i&&S(i))return{source:"dev-bridge",bridgePort:i.bridgePort,shellBaseUrl:i.shellPort?`http://localhost:${i.shellPort}/`:f};let r=y();return r&&I(r)?{source:"daemon",bridgePort:r.bridgePort,shellBaseUrl:r.runtimePort>0?`http://localhost:${r.runtimePort}/`:f}:{source:"default",bridgePort:7668,shellBaseUrl:f}}function E(i){let r=w();if(r&&S(r)&&r.bridgePort===i)return{source:"dev-bridge",shellBaseUrl:r.shellPort?`http://localhost:${r.shellPort}/`:f};let e=y();return e&&I(e)&&e.bridgePort===i?{source:"daemon",shellBaseUrl:e.runtimePort>0?`http://localhost:${e.runtimePort}/`:f}:null}function q(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=w();if(e&&S(e)&&(e.shellPort===r||e.runtimePort===r||e.bridgePort===r))return e.bridgePort;let d=y();return d&&I(d)&&(d.runtimePort===r||d.bridgePort===r)?d.bridgePort:null}function O(){return L().bridgePort}function H(i,r){let e=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 k=class extends Error{lock;constructor(r,e){super(r),this.name="BridgeSimLockedError",this.lock=e}};function M(i){return i==="flag"?"via --sim":i==="saved"?"saved via `sootsim use`":"primary fallback \u2014 no sim pinned"}function J(i,r={}){let e=new Set,d=r.port??O(),l=r.commandTimeoutMs??15e3,t,m="none",B=new Set(r.stripBooleanFlags??[]),h=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,m="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,m="flag";continue}if(B.has(a)){e.add(n);continue}h.has(a)&&(e.add(n),n+1<i.length&&e.add(n+1),n++)}if(!t){let n=W();n&&(t=n.trim()||void 0,m="saved")}return{positional:i.filter((n,a)=>!e.has(a)),wsPort:d,simId:t,simIdSource:m,commandTimeoutMs:l}}function U(i,r={}){let e=1,d=r.commandTimeoutMs??15e3,l=new Map,t=new v(`ws://localhost:${i}`),m=C(),B=new Promise((s,o)=>{t.on("open",()=>{try{t.send(JSON.stringify({type:"bridge:hello",id:0,cliIdentityKey:m.key,cliIdentitySource:m.source,cliLabel:r.cliLabel}))}catch{}s()}),t.on("error",c=>{let g=c.message?`: ${c.message}`:"";o(new Error(`could not connect to ws://localhost:${i}${g}`))})}),h=!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",g=M(o?r.simIdSource:"none");process.stderr.write(` \u2192 ${c} (${g})
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&&!h&&(h=!0,process.stderr.write(`
5
5
  \u26A0 ${o._otherCliCount} other CLI identity/identities are driving this sim
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import{createHash as b}from"node:crypto";import g from"node:fs";import{createRequire as S}from"node:module";import u from"node:path";var y=/\.(ttf|otf|woff|woff2)$/i;function P(t,n,r){if(!t||typeof t!="object")return;let o=t.fonts;if(Array.isArray(o))for(let i of o)typeof i=="string"&&r.push(i);let e=t[n];if(!e||typeof e!="object")return;let s=e.fonts;if(Array.isArray(s))for(let i of s){if(typeof i=="string"){r.push(i);continue}if(!i||typeof i!="object")continue;let c=i.fontDefinitions;if(Array.isArray(c))for(let a of c){if(!a||typeof a!="object")continue;let p=a.path;typeof p=="string"&&r.push(p)}}}function m(t,n){if(!Array.isArray(t))return[];let r=[];for(let o of t){let e=Array.isArray(o)?o[0]:o;if(typeof e!="string"||!/(^|\/)expo-font$/.test(e))continue;let s=Array.isArray(o)?o[1]??{}:{};P(s,n,r)}return r}function C(t){return t.slice(t.lastIndexOf("/")+1).replace(y,"")}function h(t,n){let r=n.replace(/\/+$/,""),o=new Set,e=[];for(let s of t){let i=s.replace(/^\.\//,"").replace(/^\/+/,"");!i||o.has(i)||(o.add(i),y.test(i)&&e.push({family:C(i),url:`${r}/assets/${i}`}))}return e}var d=S(import.meta.url);function x(t){try{let n=new URL(t),r=n.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 n.origin}catch{}return null}var R=["app.config.js","app.config.ts","app.config.cjs","app.config.mjs","app.json"];function w(t){for(let n of R)try{if(g.statSync(u.join(t,n)).isFile())return!0}catch{}return!1}var j=new Set(["node_modules","artifacts","dist","build","out","coverage","tmp","public","ios","android","macos","windows","__fixtures__","__tests__","examples","example"]);function F(t,n){w(t)&&n.push(t);let r;try{r=g.readdirSync(t,{withFileTypes:!0})}catch{return}for(let o of r)o.isDirectory()&&(o.name.startsWith(".")||j.has(o.name)||F(u.join(t,o.name),n))}function _(t){try{return g.statSync(u.join(t,"package.json")).isFile()}catch{return!1}}function I(t){let n=x(t.bundleUrl);if(!n)return[];let r=t.repoDir||process.env.SOOT_REPO_DIR,o=r?u.resolve(r):process.cwd();if(!r&&!_(o))return[];let e=[];if(r)F(o,e),e.includes(o)||e.push(o);else{if(!w(o))return[];e.push(o)}if(e.length===0)return[];let s=(t.platform||process.env.SOOT_PLATFORM||"ios").toLowerCase(),i=null;try{let l=d.resolve("@expo/config",{paths:[...e,o]}),f=d(l);typeof f.getConfig=="function"&&(i=f.getConfig)}catch{}if(!i)return[];let c;for(let l of e)try{let f=i(l,{skipSDKVersionRequirement:!0});if(f?.exp&&typeof f.exp=="object"){let A=f.exp.plugins;if(Array.isArray(A)){c=f.exp;break}}}catch{}if(!c||typeof c!="object")return[];let a=c.plugins;if(!Array.isArray(a))return[];let p=m(a,s==="android"?"android":"ios");return h(p,n)}async function L(t,n){let r=x(t);if(!r)return null;let o=new AbortController,e=setTimeout(()=>o.abort(),n?.timeoutMs??1500);try{let s=await fetch(`${r}/`,{headers:{"expo-platform":"ios",Accept:"application/json"},signal:o.signal});if(!s.ok)return null;let c=(await s.json())?.extra?.expoClient?._internal?.projectRoot;return typeof c=="string"&&c.length>0?c:null}catch{return null}finally{clearTimeout(e)}}function M(t){return t.map(n=>`${encodeURIComponent(n.url)}::${encodeURIComponent(n.family)}`).join(",")}function k(t){let n=[];for(let r of t.split(",")){let o=r.trim();if(!o)continue;let e=o.indexOf("::"),s=e===-1?o:o.slice(0,e);try{n.push(decodeURIComponent(s))}catch{n.push(s)}}return n.filter(Boolean)}function D(t){let n=(t.split("?")[0].split(".").pop()||"").toLowerCase();return n==="ttf"?"font/ttf":n==="otf"?"font/otf":n==="woff"?"font/woff":n==="woff2"?"font/woff2":"application/octet-stream"}async function G(t,n){let r=[],o=new Set;for(let e of k(t)){let s=b("sha256").update(e).digest("hex");if(!o.has(s)){o.add(s);try{let i=await fetch(e);if(!i.ok){n?.onError?.(e,new Error(`${i.status} ${i.statusText}`));continue}let c=new Uint8Array(await i.arrayBuffer());r.push({url:e,urlhash:s,contentType:D(e),bytes:c}),n?.onStaged?.({url:e,byteLength:c.byteLength})}catch(i){n?.onError?.(e,i)}}}return r}export{I as a,L as b,M as c,G as d};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as c}from"./chunk-FSJQB6FI.js";import{a as u,b as f,c as s,d as a}from"./chunk-SX5MJUQC.js";import{a as e}from"./chunk-7BH3S3L3.js";import{c as n}from"./chunk-5FQMI3PB.js";import{a as i}from"./chunk-YFXU4HRJ.js";import{a as m,c as p}from"./chunk-SC67TYH6.js";function g(){return`sootsim CLI v${i()} \xB7 ${c().primary}`}function C(){let r=f({bridgePort:7668,defaultShellUrl:n},e()),o=`
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as c}from"./chunk-DUGNFSB5.js";import{a as u,b as f,c as s,d as a}from"./chunk-TQ7WAA2M.js";import{a as e}from"./chunk-R35AOOU4.js";import{c as n}from"./chunk-BNUZWRON.js";import{a as i}from"./chunk-SLX3HZPR.js";import{a as m,c as p}from"./chunk-KHIKG5LO.js";function g(){return`sootsim CLI v${i()} \xB7 ${c().primary}`}function C(){let r=f({bridgePort:7668,defaultShellUrl:n},e()),o=`
3
3
  ${p}
4
4
  `;console.log(`${g()}
5
5
  ${o}${r}
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as l}from"./chunk-O7K44ZT6.js";import{A as o,B as s}from"./chunk-ERG3QCK4.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.SOOT_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:"soot-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.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as l}from"./chunk-6QMGV5H7.js";import{A as o,B as s}from"./chunk-TX53NA5W.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.SOOT_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:"soot-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,3 +1,3 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{o as d}from"./chunk-ERG3QCK4.js";import{chmodSync as S,existsSync as f,mkdirSync as k,readFileSync as A,rmSync as i,writeFileSync as y}from"node:fs";import{dirname as c,join as D,resolve as m}from"node:path";var s=1,p="SOOTSIM_SHARED_AUTH_FILE",u="https://sootbean.com";function w(){let t=process.env[p];return t?.trim()?c(m(t)):d()}function a(){let t=process.env[p];return t?.trim()?m(t):D(w(),"desktop-auth.json")}function g(t){if(!t||typeof t!="object")return null;let e=t;return typeof e.id!="string"||!e.id.trim()?null:{id:e.id.trim(),name:typeof e.name=="string"?e.name:void 0,email:typeof e.email=="string"?e.email:void 0,image:typeof e.image=="string"?e.image:void 0,githubUsername:typeof e.githubUsername=="string"?e.githubUsername:void 0,teams:Array.isArray(e.teams)?e.teams.map(r=>{if(!r||typeof r!="object")return null;let n=r;return typeof n.id!="string"||typeof n.name!="string"?null:{id:n.id,name:n.name,role:n.role==="owner"?"owner":"member",githubOrg:typeof n.githubOrg=="string"?n.githubOrg:null}}).filter(r=>!!r):void 0}}function v(t){if(!t||typeof t!="object")return null;let e=t;if(e.version!==s||typeof e.token!="string"||!e.token.trim())return null;let r=typeof e.origin=="string"&&e.origin.trim()?e.origin.trim():u,n=e.source==="cli"||e.source==="electron"||e.source==="browser"||e.source==="unknown"?e.source:"unknown",o=typeof e.updatedAt=="string"&&e.updatedAt?e.updatedAt:new Date().toISOString(),h=typeof e.validatedAt=="string"&&e.validatedAt?e.validatedAt:void 0;return{version:s,token:e.token.trim(),user:g(e.user),origin:r,source:n,updatedAt:o,validatedAt:h}}function b(){let t=a();if(!f(t))return null;try{let e=JSON.parse(A(t,"utf8")),r=v(e);return r||(i(t,{force:!0}),null)}catch{return i(t,{force:!0}),null}}function O(t){let e=a();k(c(e),{recursive:!0});let r={version:s,token:t.token.trim(),user:t.user?g(t.user):null,origin:t.origin?.trim()||u,source:t.source,updatedAt:t.updatedAt||new Date().toISOString(),validatedAt:t.validatedAt};y(e,JSON.stringify(r,null,2)+`
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{o as d}from"./chunk-TX53NA5W.js";import{chmodSync as S,existsSync as f,mkdirSync as k,readFileSync as A,rmSync as i,writeFileSync as y}from"node:fs";import{dirname as c,join as D,resolve as m}from"node:path";var s=1,p="SOOTSIM_SHARED_AUTH_FILE",u="https://sootbean.com";function w(){let t=process.env[p];return t?.trim()?c(m(t)):d()}function a(){let t=process.env[p];return t?.trim()?m(t):D(w(),"desktop-auth.json")}function g(t){if(!t||typeof t!="object")return null;let e=t;return typeof e.id!="string"||!e.id.trim()?null:{id:e.id.trim(),name:typeof e.name=="string"?e.name:void 0,email:typeof e.email=="string"?e.email:void 0,image:typeof e.image=="string"?e.image:void 0,githubUsername:typeof e.githubUsername=="string"?e.githubUsername:void 0,teams:Array.isArray(e.teams)?e.teams.map(r=>{if(!r||typeof r!="object")return null;let n=r;return typeof n.id!="string"||typeof n.name!="string"?null:{id:n.id,name:n.name,role:n.role==="owner"?"owner":"member",githubOrg:typeof n.githubOrg=="string"?n.githubOrg:null}}).filter(r=>!!r):void 0}}function v(t){if(!t||typeof t!="object")return null;let e=t;if(e.version!==s||typeof e.token!="string"||!e.token.trim())return null;let r=typeof e.origin=="string"&&e.origin.trim()?e.origin.trim():u,n=e.source==="cli"||e.source==="electron"||e.source==="browser"||e.source==="unknown"?e.source:"unknown",o=typeof e.updatedAt=="string"&&e.updatedAt?e.updatedAt:new Date().toISOString(),h=typeof e.validatedAt=="string"&&e.validatedAt?e.validatedAt:void 0;return{version:s,token:e.token.trim(),user:g(e.user),origin:r,source:n,updatedAt:o,validatedAt:h}}function b(){let t=a();if(!f(t))return null;try{let e=JSON.parse(A(t,"utf8")),r=v(e);return r||(i(t,{force:!0}),null)}catch{return i(t,{force:!0}),null}}function O(t){let e=a();k(c(e),{recursive:!0});let r={version:s,token:t.token.trim(),user:t.user?g(t.user):null,origin:t.origin?.trim()||u,source:t.source,updatedAt:t.updatedAt||new Date().toISOString(),validatedAt:t.validatedAt};y(e,JSON.stringify(r,null,2)+`
3
3
  `);try{S(e,384)}catch{}return r}function l(){i(a(),{force:!0})}async function E(t){let e=b();if(!e?.token)return null;let r=t||e.origin||u;try{let n=await fetch(`${r.replace(/\/$/,"")}/api/auth/me`,{headers:{authorization:`Bearer ${e.token}`}});if(n.status===401)return l(),null;if(!n.ok)return e;let o=await n.json();return o.user?.id?O({token:e.token,user:o.user,origin:r,source:e.source,validatedAt:new Date().toISOString()}):(l(),null)}catch{return e}}export{b as a,O as b,l as c,E as d};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{h as w,j as u,k as m,l}from"./chunk-AOUNFYEN.js";var p="sootsim:settings",v=["errorReporting","colorScheme","a11yMode","a11yDepth","screenshotCanvas","screenshotBackground","screenshotText","screenshotPose","screenshotDynamicSize","alwaysShowLiveWebViews","agentProvider","onboardingComplete","betaConsentVersion","detailedTelemetry"];function S(){if(typeof window>"u")return null;let e=window.sootsimElectron;return e&&typeof e=="object"?e:null}function g(e){let t={};for(let n of v){if(!(n in e))continue;let r=e[n],o=u[n];o.validate&&!o.validate(r)||o.options&&!o.options.includes(r)||(t[n]=r)}return t}function h(e){let t={};for(let n of v)t[n]=e[n];return t}function _(){if(typeof localStorage>"u")return{};try{let e=localStorage.getItem(p);return e?g(JSON.parse(e)):{}}catch{return{}}}function V(e){if(!(typeof localStorage>"u"))try{localStorage.setItem(p,JSON.stringify(h(e)))}catch{}}function E(){let t=S()?.sharedConfig?.settings;return!t||typeof t!="object"?{}:g(t)}function K(e){let t=S();if(t?.writeSharedConfig)try{t.writeSharedConfig({settings:h(e)})}catch{}}function b(){if(typeof window>"u")return null;let e=window.__sootsimSharedConfig;return e&&typeof e=="object"?e:null}function j(){let e=b()?.settings;return!e||typeof e!="object"?{}:g(e)}function D(e){if(!b())return;let t={settings:h(e)};try{if(globalThis.__sootsimBridgeRequest?.writeSharedConfig?.(t))return}catch{}if(!(typeof fetch>"u"))try{fetch("/__sootsim/shared-config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),keepalive:!0}).catch(()=>{})}catch{}}function k(){let e=_(),t=j(),n=E();return{...e,...t,...n}}function R(e){V(e),K(e),D(e)}function C(e){if(typeof window>"u")return()=>{};let t=i=>{if(!(i.key!==p||i.newValue==null))try{e(g(JSON.parse(i.newValue)))}catch{}};window.addEventListener("storage",t);let n=S(),r;n?.onSharedConfigChanged&&(r=n.onSharedConfigChanged(i=>{let d=i?.settings;!d||typeof d!="object"||e(g(d))}));let c=globalThis.__sootsimBridgeRequest?.subscribeSharedConfig?.(i=>{let d=i?.settings;!d||typeof d!="object"||e(g(d))});return()=>{window.removeEventListener("storage",t),r?.(),c?.()}}var M=l(),P=k();for(let e of Object.keys(m()))delete P[e];var s={...M,...P},f=[],a=null;function y(){for(let e of f)e();R(s)}C(e=>{let t={...s},n=!1;for(let[r,o]of Object.entries(e)){let c=r;t[c]!==o&&(t[c]=o,n=!0)}if(n){s=t,a=null;for(let r of f)r()}});var L={get(e){return s[e]},set(e,t){let n=u[e];n.validate&&!n.validate(t)||n.options&&!n.options.includes(t)||s[e]!==t&&(s={...s,[e]:t},e==="deviceModel"&&(a=null),y())},getAll(){return s},apply(e){let t=!1,n={...s};for(let[r,o]of Object.entries(e)){if(o===void 0)continue;let c=r,i=u[c];i&&(i.validate&&!i.validate(o)||i.options&&!i.options.includes(o)||n[c]!==o&&(n[c]=o,t=!0))}t&&(s=n,a=null,y())},reset(){s=l(),a=null,y()},subscribe(e){return f.push(e),()=>{f=f.filter(t=>t!==e)}},getDeviceSpec(){return a||(a=w(s.deviceModel)),a},getA11yMode(){return s.a11yMode},setA11yMode(e){this.set("a11yMode",e)},getInspectMode(){return s.inspectMode},setInspectMode(e){this.set("inspectMode",e)}};export{L as a};
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{h as w,j as u,k as m,l}from"./chunk-T7CWPTU7.js";var p="sootsim:settings",v=["errorReporting","colorScheme","a11yMode","a11yDepth","screenshotCanvas","screenshotBackground","screenshotText","screenshotPose","screenshotDynamicSize","alwaysShowLiveWebViews","agentProvider","onboardingComplete","betaConsentVersion","detailedTelemetry"];function S(){if(typeof window>"u")return null;let e=window.sootsimElectron;return e&&typeof e=="object"?e:null}function g(e){let t={};for(let n of v){if(!(n in e))continue;let r=e[n],o=u[n];o.validate&&!o.validate(r)||o.options&&!o.options.includes(r)||(t[n]=r)}return t}function h(e){let t={};for(let n of v)t[n]=e[n];return t}function _(){if(typeof localStorage>"u")return{};try{let e=localStorage.getItem(p);return e?g(JSON.parse(e)):{}}catch{return{}}}function V(e){if(!(typeof localStorage>"u"))try{localStorage.setItem(p,JSON.stringify(h(e)))}catch{}}function E(){let t=S()?.sharedConfig?.settings;return!t||typeof t!="object"?{}:g(t)}function K(e){let t=S();if(t?.writeSharedConfig)try{t.writeSharedConfig({settings:h(e)})}catch{}}function b(){if(typeof window>"u")return null;let e=window.__sootsimSharedConfig;return e&&typeof e=="object"?e:null}function j(){let e=b()?.settings;return!e||typeof e!="object"?{}:g(e)}function D(e){if(!b())return;let t={settings:h(e)};try{if(globalThis.__sootsimBridgeRequest?.writeSharedConfig?.(t))return}catch{}if(!(typeof fetch>"u"))try{fetch("/__sootsim/shared-config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),keepalive:!0}).catch(()=>{})}catch{}}function k(){let e=_(),t=j(),n=E();return{...e,...t,...n}}function R(e){V(e),K(e),D(e)}function C(e){if(typeof window>"u")return()=>{};let t=i=>{if(!(i.key!==p||i.newValue==null))try{e(g(JSON.parse(i.newValue)))}catch{}};window.addEventListener("storage",t);let n=S(),r;n?.onSharedConfigChanged&&(r=n.onSharedConfigChanged(i=>{let d=i?.settings;!d||typeof d!="object"||e(g(d))}));let c=globalThis.__sootsimBridgeRequest?.subscribeSharedConfig?.(i=>{let d=i?.settings;!d||typeof d!="object"||e(g(d))});return()=>{window.removeEventListener("storage",t),r?.(),c?.()}}var M=l(),P=k();for(let e of Object.keys(m()))delete P[e];var s={...M,...P},f=[],a=null;function y(){for(let e of f)e();R(s)}C(e=>{let t={...s},n=!1;for(let[r,o]of Object.entries(e)){let c=r;t[c]!==o&&(t[c]=o,n=!0)}if(n){s=t,a=null;for(let r of f)r()}});var L={get(e){return s[e]},set(e,t){let n=u[e];n.validate&&!n.validate(t)||n.options&&!n.options.includes(t)||s[e]!==t&&(s={...s,[e]:t},e==="deviceModel"&&(a=null),y())},getAll(){return s},apply(e){let t=!1,n={...s};for(let[r,o]of Object.entries(e)){if(o===void 0)continue;let c=r,i=u[c];i&&(i.validate&&!i.validate(o)||i.options&&!i.options.includes(o)||n[c]!==o&&(n[c]=o,t=!0))}t&&(s=n,a=null,y())},reset(){s=l(),a=null,y()},subscribe(e){return f.push(e),()=>{f=f.filter(t=>t!==e)}},getDeviceSpec(){return a||(a=w(s.deviceModel)),a},getA11yMode(){return s.a11yMode},setA11yMode(e){this.set("a11yMode",e)},getInspectMode(){return s.inspectMode},setInspectMode(e){this.set("inspectMode",e)}};export{L as a};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var t="./demo-app-registry.ts",o=null;async function n(){if(o)return o;try{let r=await import(t);o=Array.isArray(r.APPS)?r.APPS:[]}catch{o=[]}return o}function e(){return o??[]}export{n as a,e as b};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.212 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var t=4001,r="sootsim close";var o="http://localhost:5173/";export{t as a,r as b,o as c};