sootsim 0.1.36 → 0.1.38

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 (161) hide show
  1. package/README.md +20 -5
  2. package/dist-cli/bin.js +15 -20
  3. package/dist-cli/chunks/{agent-YZB6D3DR.js → agent-CGQWOOOL.js} +2 -2
  4. package/dist-cli/chunks/{agent-wrapper-VHCVS22I.js → agent-wrapper-M6P53GJ2.js} +10 -10
  5. package/dist-cli/chunks/{assert-AIVCKKLG.js → assert-O7N2SYJZ.js} +2 -2
  6. package/dist-cli/chunks/auto-bootstrap-DF4KYGPS.js +2 -0
  7. package/dist-cli/chunks/beta-AK25X3AU.js +2 -0
  8. package/dist-cli/chunks/chunk-23YMXBQ2.js +1 -0
  9. package/dist-cli/chunks/chunk-2ABGQIW7.js +4 -0
  10. package/dist-cli/chunks/chunk-5HNZO5AI.js +7 -0
  11. package/dist-cli/chunks/chunk-5XI3AB4I.js +3 -0
  12. package/dist-cli/chunks/{chunk-IJMYFYDZ.js → chunk-67K3WAEZ.js} +2 -2
  13. package/dist-cli/chunks/chunk-6UJXRT7F.js +5 -0
  14. package/dist-cli/chunks/chunk-ARH3T5NK.js +66 -0
  15. package/dist-cli/chunks/{chunk-VFDRZNPN.js → chunk-B4VH67D3.js} +1 -1
  16. package/dist-cli/chunks/chunk-BEY2QVU5.js +3 -0
  17. package/dist-cli/chunks/chunk-CB4PUMI2.js +1 -0
  18. package/dist-cli/chunks/chunk-CHMHTTI7.js +11 -0
  19. package/dist-cli/chunks/chunk-E473YTRQ.js +2 -0
  20. package/dist-cli/chunks/chunk-FCOCFEBU.js +27 -0
  21. package/dist-cli/chunks/chunk-FRE5TY3C.js +1 -0
  22. package/dist-cli/chunks/chunk-FX3PPKSJ.js +2 -0
  23. package/dist-cli/chunks/{chunk-27P763IZ.js → chunk-FXY5FWVY.js} +2 -2
  24. package/dist-cli/chunks/{chunk-A5BRCXYE.js → chunk-G23GIRBM.js} +1 -1
  25. package/dist-cli/chunks/chunk-G62Q2MQI.js +1 -0
  26. package/dist-cli/chunks/chunk-GWQUPWVO.js +2 -0
  27. package/dist-cli/chunks/{chunk-EWSQSALM.js → chunk-H6CG42HE.js} +4 -4
  28. package/dist-cli/chunks/chunk-HNAGYNWN.js +16 -0
  29. package/dist-cli/chunks/{chunk-KAXZHEKM.js → chunk-IE2WYVJF.js} +1 -1
  30. package/dist-cli/chunks/chunk-IKVIHHWE.js +2 -0
  31. package/dist-cli/chunks/chunk-JJVZMGRM.js +2 -0
  32. package/dist-cli/chunks/{chunk-HWCKZXNJ.js → chunk-LNRBXCUI.js} +2 -2
  33. package/dist-cli/chunks/{chunk-CYCXOAVZ.js → chunk-MTPWS4JK.js} +4 -4
  34. package/dist-cli/chunks/{chunk-G7XQD4KC.js → chunk-NKYTISAN.js} +2 -2
  35. package/dist-cli/chunks/chunk-NSZBULGG.js +348 -0
  36. package/dist-cli/chunks/chunk-P32FCOS3.js +4 -0
  37. package/dist-cli/chunks/chunk-P722XCFT.js +3 -0
  38. package/dist-cli/chunks/chunk-PFRPXFSL.js +117 -0
  39. package/dist-cli/chunks/chunk-QD22CQLH.js +5 -0
  40. package/dist-cli/chunks/chunk-QI4VLQ3A.js +5 -0
  41. package/dist-cli/chunks/{chunk-OXN2PEB7.js → chunk-SKNHJDYO.js} +3 -3
  42. package/dist-cli/chunks/{chunk-YIO6S3R5.js → chunk-T442FYM5.js} +1 -1
  43. package/dist-cli/chunks/chunk-TR554AIH.js +17 -0
  44. package/dist-cli/chunks/chunk-UD5ILFN5.js +3 -0
  45. package/dist-cli/chunks/{chunk-LHDWH7VS.js → chunk-VIEK76DX.js} +1 -1
  46. package/dist-cli/chunks/chunk-VVUEWU2P.js +64 -0
  47. package/dist-cli/chunks/{chunk-RMW5BO3S.js → chunk-Z2PBRNJP.js} +2 -2
  48. package/dist-cli/chunks/chunk-ZEVZN3S4.js +2 -0
  49. package/dist-cli/chunks/{compat-Y2O2U7FL.js → compat-DNQWSPFQ.js} +2 -2
  50. package/dist-cli/chunks/{config-SRBOFUCI.js → config-ABR5BGUO.js} +2 -2
  51. package/dist-cli/chunks/control-DEHRU4XZ.js +2 -0
  52. package/dist-cli/chunks/cpu-profile-Y5YDH6X2.js +22 -0
  53. package/dist-cli/chunks/daemon-2Z4DAJT6.js +83 -0
  54. package/dist-cli/chunks/{debug-BIDMW2PE.js → debug-R36UPOJP.js} +4 -4
  55. package/dist-cli/chunks/demo-app-registry-DMMWYL7G.js +2 -0
  56. package/dist-cli/chunks/detox-FQJWEWLT.js +49 -0
  57. package/dist-cli/chunks/device-SXKLDZEC.js +16 -0
  58. package/dist-cli/chunks/diagnose-M7RKNI2H.js +41 -0
  59. package/dist-cli/chunks/drivers-NSCX5CRA.js +2 -0
  60. package/dist-cli/chunks/electron-YUAKGT4H.js +18 -0
  61. package/dist-cli/chunks/flow-UQSRNEZD.js +2 -0
  62. package/dist-cli/chunks/hints-SDD7L3VS.js +2 -0
  63. package/dist-cli/chunks/home-paths-QMCX2227.js +2 -0
  64. package/dist-cli/chunks/inspect-6FPPW7GS.js +1101 -0
  65. package/dist-cli/chunks/install-TTH3PM3B.js +2 -0
  66. package/dist-cli/chunks/{install-desktop-2MYEI4FM.js → install-desktop-EKMYRDQH.js} +3 -3
  67. package/dist-cli/chunks/{keys-7PNASIQR.js → keys-ODG3TDUP.js} +2 -2
  68. package/dist-cli/chunks/{launch-JNS47LAQ.js → launch-7HUL745I.js} +3 -3
  69. package/dist-cli/chunks/{login-YWZWUHBS.js → login-BJKQMJYT.js} +4 -4
  70. package/dist-cli/chunks/{logout-O6SXMSBP.js → logout-7NG3KGJD.js} +2 -2
  71. package/dist-cli/chunks/maestro-VFEUWV3Q.js +80 -0
  72. package/dist-cli/chunks/{preview-WGKJO5FS.js → preview-WZ6XNOBC.js} +2 -2
  73. package/dist-cli/chunks/profile-DXFEZOHB.js +22 -0
  74. package/dist-cli/chunks/react-QP7PL5CZ.js +30 -0
  75. package/dist-cli/chunks/{record-QPWLYH5R.js → record-AFE25EMH.js} +5 -5
  76. package/dist-cli/chunks/{runtime-KEMO2MSB.js → runtime-GFWS3QLZ.js} +3 -3
  77. package/dist-cli/chunks/screenshot-U6VFOVFW.js +28 -0
  78. package/dist-cli/chunks/screenshot-mode-HNGV3AFC.js +17 -0
  79. package/dist-cli/chunks/screenshots-GYMRDUJR.js +70 -0
  80. package/dist-cli/chunks/server-3Q22YYM6.js +35 -0
  81. package/dist-cli/chunks/setup-repo-NNDWIGZR.js +2 -0
  82. package/dist-cli/chunks/{skills-MO7BFNVM.js → skills-FT76ZVAV.js} +2 -2
  83. package/dist-cli/chunks/start-N573LFCF.js +23 -0
  84. package/dist-cli/chunks/store-6NTDGLPH.js +2 -0
  85. package/dist-cli/chunks/telemetry-SNZBIRGL.js +2 -0
  86. package/dist-cli/chunks/{test-XUI3KNNQ.js → test-AJPY2Q6W.js} +3 -3
  87. package/dist-cli/chunks/three-mode-JZZVOMTG.js +39 -0
  88. package/dist-cli/chunks/timeline-GTSCF5P6.js +22 -0
  89. package/dist-cli/chunks/upload-UHTVCGGR.js +2 -0
  90. package/dist-cli/chunks/what-happened-N3AQ6I7O.js +15 -0
  91. package/dist-cli/chunks/whoami-FOIMN6UC.js +2 -0
  92. package/dist-lib/agent-daemon-client.cjs +4 -1
  93. package/dist-lib/agent-events.cjs +1 -1
  94. package/dist-lib/agent-sessions.cjs +41 -39
  95. package/dist-lib/attached-projects.cjs +30 -28
  96. package/dist-lib/auth/shared-session.cjs +35 -27
  97. package/dist-lib/backend-origin.cjs +1 -1
  98. package/dist-lib/bridge-constants.cjs +1 -1
  99. package/dist-lib/cli-constants.cjs +1 -1
  100. package/dist-lib/config.cjs +6 -2
  101. package/dist-lib/dev-bundle-resolution.cjs +5 -50
  102. package/dist-lib/home-paths.cjs +94 -38
  103. package/dist-lib/host/bridge-host.cjs +2144 -1330
  104. package/dist-lib/host/fetch-proxy-handler.cjs +248 -0
  105. package/dist-lib/index.cjs +21 -21
  106. package/dist-lib/metro.cjs +21 -21
  107. package/dist-lib/profiles.cjs +246 -0
  108. package/dist-lib/render-mode.cjs +1 -1
  109. package/dist-lib/vite-base.cjs +3410 -1632
  110. package/dist-lib/vite.cjs +1 -1
  111. package/package.json +7 -1
  112. package/dist-cli/chunks/auto-bootstrap-MLNTX23H.js +0 -2
  113. package/dist-cli/chunks/chunk-3UIWOHC2.js +0 -62
  114. package/dist-cli/chunks/chunk-5KGFHWVR.js +0 -1
  115. package/dist-cli/chunks/chunk-5QIUJNT3.js +0 -5
  116. package/dist-cli/chunks/chunk-6GGMKFWJ.js +0 -4
  117. package/dist-cli/chunks/chunk-6Z275LCY.js +0 -2
  118. package/dist-cli/chunks/chunk-75LBYBKW.js +0 -11
  119. package/dist-cli/chunks/chunk-DFN3GGH7.js +0 -5
  120. package/dist-cli/chunks/chunk-EBEHZJRG.js +0 -117
  121. package/dist-cli/chunks/chunk-EJLNUMMP.js +0 -3
  122. package/dist-cli/chunks/chunk-FE7UI3MT.js +0 -4
  123. package/dist-cli/chunks/chunk-G663654J.js +0 -1
  124. package/dist-cli/chunks/chunk-GW7XY5KC.js +0 -2
  125. package/dist-cli/chunks/chunk-H2QO4TDV.js +0 -22
  126. package/dist-cli/chunks/chunk-HWFHBMAQ.js +0 -27
  127. package/dist-cli/chunks/chunk-J7CTD37P.js +0 -1
  128. package/dist-cli/chunks/chunk-N32NCVL2.js +0 -3
  129. package/dist-cli/chunks/chunk-NIZBR7EK.js +0 -2
  130. package/dist-cli/chunks/chunk-NYY36OKU.js +0 -308
  131. package/dist-cli/chunks/chunk-PJL25JQV.js +0 -5
  132. package/dist-cli/chunks/chunk-SHO54NET.js +0 -2
  133. package/dist-cli/chunks/chunk-SMVJOWSV.js +0 -16
  134. package/dist-cli/chunks/chunk-TC6V7YFC.js +0 -3
  135. package/dist-cli/chunks/chunk-YLIIVTTQ.js +0 -3
  136. package/dist-cli/chunks/chunk-YR7BGGYE.js +0 -2
  137. package/dist-cli/chunks/chunk-ZEW3RF5Q.js +0 -1
  138. package/dist-cli/chunks/control-PL2V2O6S.js +0 -2
  139. package/dist-cli/chunks/daemon-IZC32PZW.js +0 -50
  140. package/dist-cli/chunks/demo-app-registry-5JFOUU3D.js +0 -2
  141. package/dist-cli/chunks/detox-B3FDOIS3.js +0 -49
  142. package/dist-cli/chunks/device-ZZSI363W.js +0 -16
  143. package/dist-cli/chunks/drivers-S4NGK4DB.js +0 -2
  144. package/dist-cli/chunks/electron-5YFHXEOI.js +0 -15
  145. package/dist-cli/chunks/flow-JJBO6TFY.js +0 -2
  146. package/dist-cli/chunks/hints-G5HBBV2O.js +0 -2
  147. package/dist-cli/chunks/home-paths-VWC3FWA3.js +0 -2
  148. package/dist-cli/chunks/inspect-POOPWUQI.js +0 -1034
  149. package/dist-cli/chunks/install-MP6FHXNZ.js +0 -2
  150. package/dist-cli/chunks/install-dev-desktop-SKH3KEHY.js +0 -100
  151. package/dist-cli/chunks/maestro-CW6XVUKV.js +0 -75
  152. package/dist-cli/chunks/profile-SUOBRPIC.js +0 -22
  153. package/dist-cli/chunks/screenshot-JTY46V7G.js +0 -26
  154. package/dist-cli/chunks/screenshot-mode-7OYBBX6D.js +0 -17
  155. package/dist-cli/chunks/screenshots-QISKC4GD.js +0 -70
  156. package/dist-cli/chunks/server-YSFJAKAV.js +0 -34
  157. package/dist-cli/chunks/setup-repo-LFB3HBEO.js +0 -2
  158. package/dist-cli/chunks/store-6MFL53I4.js +0 -2
  159. package/dist-cli/chunks/telemetry-CN42GMVC.js +0 -2
  160. package/dist-cli/chunks/upload-6FUT7AX5.js +0 -2
  161. package/dist-cli/chunks/whoami-TQFHY42N.js +0 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # sootsim
2
2
 
3
- CLI + framework plugins for soot's iOS simulator.
3
+ CLI + framework plugins for soot's browser-native simulator.
4
4
 
5
5
  this package is the public, publishable face of sootsim. it contains:
6
6
 
@@ -10,9 +10,21 @@ this package is the public, publishable face of sootsim. it contains:
10
10
  - `sootsim/metro` — metro plugin for wrapping a react native bundler
11
11
  - `sootsim/skills` — registry for soot-flavored automation skills
12
12
 
13
- the rendering engine itself (canvas renderer, yoga layout, ios shell, wasm,
14
- electron shell) lives in the private `sootsim-engine` workspace package and
15
- is not published.
13
+ the rendering engine itself (canvas renderer, yoga layout, iOS/Android shell
14
+ chrome, wasm, electron shell) lives in the private `sootsim-engine` workspace
15
+ package and is not published.
16
+
17
+ Platform status: iOS is the parity baseline. Android is bootstrapped and
18
+ usable for focused conformance slices, with Android bundle/runtime identity,
19
+ device profiles, initial shell chrome, gesture and three-button nav proof,
20
+ Android system UI/window metrics with cutout-safe insets, and Android
21
+ sootsim-only matrix runs.
22
+ Android `react-native-screens`, `react-native-safe-area-context`,
23
+ RefreshControl, keyboard/IME resize, EdgeEffect, scroll deceleration/fading
24
+ edges/scrollbars, and basic system-bar API support are improving but still need
25
+ the Android launch gates before this can be called full parity.
26
+ It is not full Android parity until the Android launch gates in the soot repo
27
+ plan pass.
16
28
 
17
29
  ## getting started
18
30
 
@@ -25,6 +37,9 @@ sootsim open 8081 # load a running metro/expo dev server
25
37
  that's the canonical path — CLI first. the bridge daemon registers itself on
26
38
  first use; you don't need to run anything to install it. a desktop GUI
27
39
  (Electron) is optional on top of that, see `sootsim install-desktop`.
40
+ In Electron, `File > New Window` duplicates the focused simulator, while
41
+ `File > New Simulator >` opens a new simulator window for a selected device
42
+ using the same device list as `Window >`.
28
43
 
29
44
  ## CLI
30
45
 
@@ -143,7 +158,7 @@ compose:
143
158
  bun sootsim screenshots --plan .sootsim/app-store.yaml
144
159
  ```
145
160
 
146
- the plan runner can reuse a visible session for capture (`--session tab-9`),
161
+ the plan runner can reuse a visible sim for capture (`--sim a9`),
147
162
  stop after raw/framed intermediates (`--capture-only`), or rerender final
148
163
  marketing canvases from an existing raw directory (`--compose-only`).
149
164
 
package/dist-cli/bin.js CHANGED
@@ -1,35 +1,30 @@
1
1
  #!/usr/bin/env node
2
- /*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
3
- import{a as b,b as f,c as k,d as A,e as g,f as v}from"./chunks/chunk-EBEHZJRG.js";import{a as u}from"./chunks/chunk-RMW5BO3S.js";import"./chunks/chunk-6Z275LCY.js";import{a as l}from"./chunks/chunk-SHO54NET.js";import"./chunks/chunk-ZEW3RF5Q.js";import"./chunks/chunk-LHDWH7VS.js";function p(){let o=f({bridgePort:7668,defaultShellUrl:l},u());console.log(`${o}
2
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
3
+ import{a as b,b as A,c as k,d as _,e as u,f as E}from"./chunks/chunk-PFRPXFSL.js";import{a as l}from"./chunks/chunk-Z2PBRNJP.js";import{a as p}from"./chunks/chunk-FX3PPKSJ.js";import{a as S,d as v}from"./chunks/chunk-IKVIHHWE.js";import"./chunks/chunk-ZEVZN3S4.js";import"./chunks/chunk-23YMXBQ2.js";import"./chunks/chunk-VIEK76DX.js";function g(){let e=A({bridgePort:7668,defaultShellUrl:p},l()),t=`
4
+ ${v}
5
+ `;console.log(`${t}${e}
4
6
 
5
7
  auth:
6
8
  sootsim login sign in for desktop uploads
7
9
  sootsim logout clear the shared desktop session
8
10
  sootsim whoami show the current shared desktop account
9
- `)}function S(){console.log(`sootsim \u2014 iOS simulator for web/react native apps
10
-
11
- getting started:
12
- npm i -g sootsim
13
- cd my-app && sootsim setup-repo # auto-fetches the engine + wires up your bundler
14
-
15
- optional desktop companion:
16
- sootsim install-desktop # download the packaged Electron GUI (prod)
17
- sootsim install-dev-desktop # create a Spotlight-launchable sootsim-dev.app
18
- # that wraps this checkout's unpacked electron
19
- `)}function _(o){let t=b(o,{bridgePort:7668,defaultShellUrl:l},u());return t?(console.log(`${t}
20
- `),!0):!1}function O(o){if(o==="login"){console.log(`sootsim login
11
+ `)}function T(e){let t=b(e,{bridgePort:7668,defaultShellUrl:p},l());return t?(console.log(`${t}
12
+ `),!0):!1}function h(e){if(e==="3d-mode"){h("three-mode");return}if(e==="login"){console.log(`sootsim login
21
13
 
22
14
  sign in for desktop uploads using the shared desktop session.
23
15
  opens the browser and stores the resulting bearer token for both the CLI and electron.
24
- `);return}if(o==="logout"){console.log(`sootsim logout
16
+ `);return}if(e==="logout"){console.log(`sootsim logout
25
17
 
26
18
  clear the shared desktop session used by the CLI and electron.
27
- `);return}if(o==="whoami"){console.log(`sootsim whoami
19
+ `);return}if(e==="whoami"){console.log(`sootsim whoami
28
20
 
29
21
  show the current shared desktop account used by the CLI and electron.
30
- `);return}let t=k(o,{bridgePort:7668,defaultShellUrl:l});if(!t){console.log(`unknown command: ${o}`);return}console.log(`${t}
31
- `)}var L=typeof __SOOTSIM_STANDALONE__<"u"&&__SOOTSIM_STANDALONE__,E=new Set(["preview","electron","install-desktop","install-dev-desktop"]);function y(o){!L||!E.has(o)||(process.stderr.write(` sootsim ${o} isn't available in the standalone binary \u2014
22
+ `);return}let t=k(e,{bridgePort:7668,defaultShellUrl:p});if(!t){console.log(`unknown command: ${e}`);return}console.log(`${t}
23
+ `)}function C(e){let t=e instanceof Error?e.message:String(e);(/^command timed out after \d+s$/.test(t)||t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("no sim connected with id ")||t.startsWith("sootsim bridge daemon is not running")||t.startsWith("refusing to install the persistent sootsim daemon"))&&!process.env.SOOTSIM_VERBOSE&&(process.stderr.write(` ${t}
24
+ `),process.exit(1)),e instanceof Error&&e.stack?process.stderr.write(`${e.stack}
25
+ `):process.stderr.write(`${t}
26
+ `),process.exit(1)}process.on("unhandledRejection",C);process.on("uncaughtException",C);var y=typeof __SOOTSIM_STANDALONE__<"u"&&__SOOTSIM_STANDALONE__,$=new Set(["preview","electron","install-desktop"]);function D(e){!y||!$.has(e)||(process.stderr.write(` sootsim ${e} isn't available in the standalone binary \u2014
32
27
  it needs vite / electron / playwright from a project's node_modules.
33
28
  install the npm package and run via bun or node instead:
34
- npm i -g sootsim && sootsim ${o}
35
- `),process.exit(1))}var e=v(process.argv);{let{trackCliEvent:o}=await import("./chunks/telemetry-CN42GMVC.js");o({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}})}async function c(o){let{flushCliTelemetry:t}=await import("./chunks/telemetry-CN42GMVC.js");await t(),process.exit(o)}if(e.version){let{readFileSync:o}=await import("fs"),{fileURLToPath:t}=await import("url"),i=t(import.meta.resolve("sootsim/package.json")),m=JSON.parse(o(i,"utf8"));console.log(`sootsim v${m.version}`),await c(0)}e.help&&!e.command&&(p(),await c(0));var a=e.globalFlags.port,r=e.verbose,d=e.globalFlags.device,h=e.globalFlags.theme,I=e.globalFlags.driver,$=e.globalFlags.headless===!0,C=e.globalFlags.session||e.globalFlags.tab||e.globalFlags.id,n=C?["--session",C,...e.commandArgs]:e.commandArgs;if(d||h){let{settingsStore:o}=await import("./chunks/store-6MFL53I4.js"),t={};d&&(t.deviceModel=d),h&&(t.colorScheme=h),o.apply(t)}!e.command&&e.commandArgs.length===0&&(S(),p(),await c(0));var s=e.command??"";s||(p(),await c(e.commandArgs.length>0?1:0));if(s in g){let o=g[s],t=e.commandArgs.length>0?` ${e.commandArgs.join(" ")}`:"";console.error(` \`sootsim ${s}\` was removed. use \`${o}\` instead.`),t&&console.error(` \u2192 ${o}${t}`),console.error(" run `sootsim --help` to see the new verb groups."),await c(1)}if(e.help||e.commandArgs.includes("--help")||e.commandArgs.includes("-h")){let o=s==="do"||s==="get"||s==="debug"||s==="shell"||s==="wait",t=e.commandArgs.find(i=>!i.startsWith("-"));s==="shell"||(o&&!t?_(s)&&await c(0):(O(o&&t?t:s),await c(0)))}y(s);if(A.has(s)){let{ensureSootsimReady:o,resolveBootstrapPort:t}=await import("./chunks/auto-bootstrap-MLNTX23H.js"),i=t(n,a);await o(i);let{runInspect:m}=await import("./chunks/inspect-POOPWUQI.js");await m([s,...n],{port:i,verbose:r})}else switch(s){case"assert":{let{runAssert:o}=await import("./chunks/assert-AIVCKKLG.js");await o(e.commandArgs);break}case"flow":{let{runFlow:o}=await import("./chunks/flow-JJBO6TFY.js"),t=await o(n);process.exit(typeof t=="number"?t:0)}case"test":{let{runTest:o}=await import("./chunks/test-XUI3KNNQ.js");await o(e.commandArgs,{port:a,verbose:r});break}case"detox":{let{runDetox:o}=await import("./chunks/detox-B3FDOIS3.js");await o(e.commandArgs,{port:a,verbose:r});break}case"maestro":{let{runMaestro:o}=await import("./chunks/maestro-CW6XVUKV.js"),t=await o(e.commandArgs,{port:a,verbose:r});process.exit(typeof t=="number"?t:0)}case"preview":{let{runPreview:o}=await import("./chunks/preview-WGKJO5FS.js");await o(e.commandArgs,{port:a,verbose:r});break}case"record":{let{runRecord:o}=await import("./chunks/record-QPWLYH5R.js");await o(n,{port:a,verbose:r});break}case"profile":{let{runProfile:o}=await import("./chunks/profile-SUOBRPIC.js"),t=await o(n,{port:a,verbose:r});process.exit(typeof t=="number"?t:0)}case"screenshot":{let{runScreenshot:o}=await import("./chunks/screenshot-JTY46V7G.js");await o(n,{port:a,verbose:r});break}case"screenshots":{let{runScreenshots:o}=await import("./chunks/screenshots-QISKC4GD.js"),t=await o(n,{port:a,verbose:r});process.exit(typeof t=="number"?t:0)}case"screenshot-mode":{let{runScreenshotMode:o}=await import("./chunks/screenshot-mode-7OYBBX6D.js");await o(e.commandArgs,{port:a,verbose:r});break}case"inspect":{let{runInspect:o}=await import("./chunks/inspect-POOPWUQI.js");await o(n,{port:a,verbose:r});break}case"debug":{let{runDebug:o}=await import("./chunks/debug-BIDMW2PE.js");await o(n,{port:a,verbose:r});break}case"open":{let{ensureSootsimReady:o,resolveBootstrapPort:t}=await import("./chunks/auto-bootstrap-MLNTX23H.js"),i=t(n,a);await o(i);let{runOpenCommand:m}=await import("./chunks/control-PL2V2O6S.js");await m(n,{port:i});break}case"use":case"focus":{let{runUseCommand:o}=await import("./chunks/control-PL2V2O6S.js");await o(n,{port:a});break}case"claim":{let{runClaimCommand:o}=await import("./chunks/control-PL2V2O6S.js");await o(n,{port:a});break}case"close":{let{runCloseCommand:o}=await import("./chunks/control-PL2V2O6S.js");await o(n,{port:a});break}case"config":{let{runConfig:o}=await import("./chunks/config-SRBOFUCI.js");await o(e.commandArgs);break}case"device":{let{runDeviceCommand:o}=await import("./chunks/device-ZZSI363W.js");await o(n,{port:a});break}case"scan":case"compat":{let{runCompat:o}=await import("./chunks/compat-Y2O2U7FL.js");await o(e.commandArgs);break}case"electron":{let{runElectron:o}=await import("./chunks/electron-5YFHXEOI.js");await o(e.commandArgs,{port:a,device:d,driver:I});break}case"login":{let{runLogin:o}=await import("./chunks/login-YWZWUHBS.js");await o(e.commandArgs);break}case"logout":{let{runLogout:o}=await import("./chunks/logout-O6SXMSBP.js");await o();break}case"whoami":{let{runWhoami:o}=await import("./chunks/whoami-TQFHY42N.js");await o();break}case"keys":{let{runKeys:o}=await import("./chunks/keys-7PNASIQR.js");await o(e.commandArgs);break}case"setup-repo":{let{runSetupRepo:o}=await import("./chunks/setup-repo-LFB3HBEO.js");await o(e.commandArgs);break}case"install":{let{runInstall:o}=await import("./chunks/install-MP6FHXNZ.js");await o(e.commandArgs);break}case"install-desktop":{let{runInstallDesktop:o}=await import("./chunks/install-desktop-2MYEI4FM.js");await o(e.commandArgs);break}case"install-dev-desktop":{let{runInstallDevDesktop:o}=await import("./chunks/install-dev-desktop-SKH3KEHY.js");await o(e.commandArgs);break}case"server":{let{runServer:o}=await import("./chunks/server-YSFJAKAV.js");await o(e.commandArgs,{port:a});break}case"daemon":{let{runDaemon:o}=await import("./chunks/daemon-IZC32PZW.js");await o(e.commandArgs,{port:a});break}case"runtime":{let{runRuntime:o}=await import("./chunks/runtime-KEMO2MSB.js");await o(e.commandArgs);break}case"launch":{let{runLaunch:o}=await import("./chunks/launch-JNS47LAQ.js");await o(e.commandArgs);break}case"agent":{let{runAgentCommand:o}=await import("./chunks/agent-YZB6D3DR.js"),t=await o(e.commandArgs);process.exit(t)}case"agent-wrapper":{let{runAgentWrapper:o}=await import("./chunks/agent-wrapper-VHCVS22I.js"),t=await o(e.commandArgs);process.exit(t)}case"skills":{let{runSkills:o}=await import("./chunks/skills-MO7BFNVM.js");await o(e.commandArgs);break}case"upload":{let{runUpload:o}=await import("./chunks/upload-6FUT7AX5.js");await o(e.commandArgs,{port:a,verbose:r});break}case"hints":{let{runHints:o}=await import("./chunks/hints-G5HBBV2O.js");o(e.commandArgs);break}default:console.error(` unknown command: ${s}`),console.error(" run `sootsim --help` to see the full surface."),process.exit(1)}
29
+ npm i -g sootsim && sootsim ${e}
30
+ `),process.exit(1))}var o=E(process.argv);{let{trackCliEvent:e}=await import("./chunks/telemetry-SNZBIRGL.js");e({event:"cli_command_invoked",properties:{command:o.command||(o.version?"version":o.help?"help":"none"),arg_count:o.commandArgs.length,platform:process.platform,arch:process.arch,node_version:process.versions.node}})}async function c(e){let{flushCliTelemetry:t}=await import("./chunks/telemetry-SNZBIRGL.js");await t(),process.exit(e)}if(o.version){let{readFileSync:e}=await import("fs"),{fileURLToPath:t}=await import("url"),i=t(import.meta.resolve("sootsim/package.json")),m=JSON.parse(e(i,"utf8")),{IS_BETA:O,BETA_LABEL:x}=await import("./chunks/beta-AK25X3AU.js"),I=O?` \xB7 ${x}`:"";console.log(`sootsim v${m.version}${I}`),await c(0)}o.help&&!o.command&&(g(),await c(0));var a=o.globalFlags.port,s=o.verbose,d=o.globalFlags.device,f=o.globalFlags.theme,N=o.globalFlags.driver,G=o.globalFlags.headless===!0,L=o.globalFlags.sim,r=L?["--sim",L,...o.commandArgs]:o.commandArgs;if(d||f){let{settingsStore:e}=await import("./chunks/store-6NTDGLPH.js"),t={};d&&(t.deviceModel=d),f&&(t.colorScheme=f),e.apply(t)}if(!o.command&&o.commandArgs.length===0){let{runStart:e}=await import("./chunks/start-N573LFCF.js");await e([],{port:a}),await c(0)}var n=o.command??"";n||(g(),await c(o.commandArgs.length>0?1:0));if(n in u){let e=u[n],t=o.commandArgs.length>0?` ${o.commandArgs.join(" ")}`:"";console.error(` \`sootsim ${n}\` was removed. use \`${e}\` instead.`),t&&console.error(` \u2192 ${e}${t}`),console.error(" run `sootsim --help` to see the new verb groups."),await c(1)}if(o.help||o.commandArgs.includes("--help")||o.commandArgs.includes("-h")){let e=n==="do"||n==="get"||n==="debug"||n==="shell"||n==="wait",t=o.commandArgs.find(i=>!i.startsWith("-"));n==="shell"||(e&&!t?T(n)&&await c(0):(h(e&&t?t:n),await c(0)))}D(n);if(_.has(n)){let{ensureSootsimReady:e,resolveBootstrapPort:t}=await import("./chunks/auto-bootstrap-DF4KYGPS.js"),i=t(r,a);await e(i);let{runInspect:m}=await import("./chunks/inspect-6FPPW7GS.js");await m([n,...r],{port:i,verbose:s})}else switch(n){case"assert":{let{runAssert:e}=await import("./chunks/assert-O7N2SYJZ.js");await e(o.commandArgs);break}case"flow":{let{runFlow:e}=await import("./chunks/flow-UQSRNEZD.js"),t=await e(r);process.exit(typeof t=="number"?t:0)}case"test":{let{runTest:e}=await import("./chunks/test-AJPY2Q6W.js");await e(o.commandArgs,{port:a,verbose:s});break}case"detox":{let{runDetox:e}=await import("./chunks/detox-FQJWEWLT.js");await e(o.commandArgs,{port:a,verbose:s});break}case"maestro":{let{runMaestro:e}=await import("./chunks/maestro-VFEUWV3Q.js"),t=await e(o.commandArgs,{port:a,verbose:s});process.exit(typeof t=="number"?t:0)}case"preview":{let{runPreview:e}=await import("./chunks/preview-WZ6XNOBC.js");await e(o.commandArgs,{port:a,verbose:s});break}case"record":{let{runRecord:e}=await import("./chunks/record-AFE25EMH.js");await e(r,{port:a,verbose:s});break}case"profile":{let{runProfile:e}=await import("./chunks/profile-DXFEZOHB.js"),t=await e(o.commandArgs,{port:a,verbose:s});process.exit(typeof t=="number"?t:0)}case"cpu-profile":{let{runCpuProfile:e}=await import("./chunks/cpu-profile-Y5YDH6X2.js"),t=await e(r,{port:a,verbose:s});process.exit(typeof t=="number"?t:0)}case"react":{let{runReact:e}=await import("./chunks/react-QP7PL5CZ.js"),t=await e(r,{port:a,verbose:s});process.exit(typeof t=="number"?t:0)}case"screenshot":{let{runScreenshot:e}=await import("./chunks/screenshot-U6VFOVFW.js");await e(r,{port:a,verbose:s});break}case"screenshots":{let{runScreenshots:e}=await import("./chunks/screenshots-GYMRDUJR.js"),t=await e(r,{port:a,verbose:s});process.exit(typeof t=="number"?t:0)}case"screenshot-mode":{let{runScreenshotMode:e}=await import("./chunks/screenshot-mode-HNGV3AFC.js");await e(o.commandArgs,{port:a,verbose:s});break}case"three-mode":case"3d-mode":{let{runThreeMode:e}=await import("./chunks/three-mode-JZZVOMTG.js");await e(o.commandArgs,{port:a,verbose:s});break}case"inspect":{let{runInspect:e}=await import("./chunks/inspect-6FPPW7GS.js");await e(r,{port:a,verbose:s});break}case"debug":{let{runDebug:e}=await import("./chunks/debug-R36UPOJP.js");await e(r,{port:a,verbose:s});break}case"timeline":{let{runTimeline:e}=await import("./chunks/timeline-GTSCF5P6.js");await e(r,{port:a,verbose:s});break}case"what-happened":{let{runWhatHappened:e}=await import("./chunks/what-happened-N3AQ6I7O.js");await e(r,{port:a,verbose:s});break}case"diagnose":{let{runDiagnose:e}=await import("./chunks/diagnose-M7RKNI2H.js"),t=await e(r,{port:a,verbose:s});process.exit(typeof t=="number"?t:0)}case"open":{let{ensureSootsimReady:e,resolveBootstrapPort:t}=await import("./chunks/auto-bootstrap-DF4KYGPS.js"),i=t(r,a);await e(i);let{runOpenCommand:m}=await import("./chunks/control-DEHRU4XZ.js");await m(r,{port:i});break}case"use":case"focus":{let{runUseCommand:e}=await import("./chunks/control-DEHRU4XZ.js");await e(r,{port:a});break}case"claim":{let{runClaimCommand:e}=await import("./chunks/control-DEHRU4XZ.js");await e(r,{port:a});break}case"close":{let{runCloseCommand:e}=await import("./chunks/control-DEHRU4XZ.js");await e(r,{port:a});break}case"config":{let{runConfig:e}=await import("./chunks/config-ABR5BGUO.js");await e(o.commandArgs);break}case"device":{let{runDeviceCommand:e}=await import("./chunks/device-SXKLDZEC.js");await e(r,{port:a});break}case"scan":case"compat":{let{runCompat:e}=await import("./chunks/compat-DNQWSPFQ.js");await e(o.commandArgs);break}case"electron":{let{runElectron:e}=await import("./chunks/electron-YUAKGT4H.js");await e(o.commandArgs,{port:a,device:d,driver:N});break}case"login":{let{runLogin:e}=await import("./chunks/login-BJKQMJYT.js");await e(o.commandArgs);break}case"logout":{let{runLogout:e}=await import("./chunks/logout-7NG3KGJD.js");await e();break}case"whoami":{let{runWhoami:e}=await import("./chunks/whoami-FOIMN6UC.js");await e();break}case"keys":{let{runKeys:e}=await import("./chunks/keys-ODG3TDUP.js");await e(o.commandArgs);break}case"setup-repo":{let{runSetupRepo:e}=await import("./chunks/setup-repo-NNDWIGZR.js");await e(o.commandArgs);break}case"install":{let{runInstall:e}=await import("./chunks/install-TTH3PM3B.js");await e(o.commandArgs);break}case"install-desktop":{let{runInstallDesktop:e}=await import("./chunks/install-desktop-EKMYRDQH.js");await e(o.commandArgs);break}case"server":{let{runServer:e}=await import("./chunks/server-3Q22YYM6.js");await e(o.commandArgs,{port:a});break}case"daemon":{let{runDaemon:e}=await import("./chunks/daemon-2Z4DAJT6.js");await e(o.commandArgs,{port:a});break}case"runtime":{let{runRuntime:e}=await import("./chunks/runtime-GFWS3QLZ.js");await e(o.commandArgs);break}case"launch":{let{runLaunch:e}=await import("./chunks/launch-7HUL745I.js");await e(o.commandArgs);break}case"start":{let{runStart:e}=await import("./chunks/start-N573LFCF.js");await e(o.commandArgs,{port:a});break}case"agent":{let{runAgentCommand:e}=await import("./chunks/agent-CGQWOOOL.js"),t=await e(o.commandArgs);process.exit(t)}case"agent-wrapper":{let{runAgentWrapper:e}=await import("./chunks/agent-wrapper-M6P53GJ2.js"),t=await e(o.commandArgs);process.exit(t)}case"skills":{let{runSkills:e}=await import("./chunks/skills-FT76ZVAV.js");await e(o.commandArgs);break}case"upload":{let{runUpload:e}=await import("./chunks/upload-UHTVCGGR.js");await e(o.commandArgs,{port:a,verbose:s});break}case"hints":{let{runHints:e}=await import("./chunks/hints-SDD7L3VS.js");e(o.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.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as y,b as $,c as b,d as l,e as E,g as A,h as j,j as S,m as I,n as T,o as x,p as g,q as k,r as D}from"./chunk-FE7UI3MT.js";import"./chunk-KAXZHEKM.js";import"./chunk-ZEW3RF5Q.js";import"./chunk-LHDWH7VS.js";import w from"node:fs";import d from"node:path";import{spawn as N}from"node:child_process";import U from"node:net";import{WebSocket as O}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 O(`ws://localhost:${this.port}`),this.ready=new Promise((t,s)=>{let r=()=>{this.ws.off("error",o),t()},o=i=>{this.ws.off("open",r),s(new c(`could not connect to sootsim daemon on port ${this.port}: ${i.message}`,"NO_DAEMON"))};this.ws.once("open",r),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 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!==O.OPEN)throw new c("daemon connection is closed","NO_DAEMON");let s=this.nextId++;return new Promise((r,o)=>{let i=setTimeout(()=>{this.pending.delete(s),o(new c(`${e} timed out after ${Math.round(this.commandTimeoutMs/1e3)}s`,"TIMEOUT"))},this.commandTimeoutMs);this.pending.set(s,{resolve:r,reject:o,timer:i});try{this.ws.send(JSON.stringify({id:s,type:e,...t}))}catch(a){clearTimeout(i),this.pending.delete(s),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 r of this.eventListeners)try{r({sessionId:t.sessionId,event:t.event})}catch{}return}if(t.type==="agent:session-status"){for(let r of this.statusListeners)try{r(t.session)}catch{}return}if(typeof t.id!="number")return;let s=this.pending.get(t.id);s&&(this.pending.delete(t.id),clearTimeout(s.timer),t.error?s.reject(new c(t.error,t.code)):s.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 R(n=7668,e=400){return new Promise(t=>{let s=new U.Socket,r=!1,o=i=>{r||(r=!0,s.destroy(),t(i))};s.setTimeout(e),s.once("connect",()=>o(!0)),s.once("timeout",()=>o(!1)),s.once("error",()=>o(!1)),s.connect(n,"127.0.0.1")})}async function _(n={}){let e=n.port??7668;if(await R(e))return{alreadyRunning:!0};let{cmd:t,prefixArgs:s}=D(),r=[...s,"server","--quiet"];e!==7668&&r.push("--port",String(e));let o=N(t,r,{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 R(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 server\` manually to diagnose.`,"SPAWN_TIMEOUT")}async function h(n={}){await _({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 ue(n){let[e,...t]=n;try{switch(e){case void 0:case"--help":case"-h":case"help":return C(),0;case"attach":return await F(t);case"projects":return await B();case"project":return await W(t);case"sessions":return await J(t);case"start":return await V(t);case"prompt":return await q(t);case"watch":return await G(t);case"transcript":return await H(t);case"end":return await K(t);case"paths":return await z();default:return process.stderr.write(`unknown agent subcommand: ${e}
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as y,b as $,c as b,d as l,e as E,g as A,h as j,j as S,m as I,n as T,o as x,p as g,q as k,r as D}from"./chunk-P32FCOS3.js";import"./chunk-IE2WYVJF.js";import"./chunk-23YMXBQ2.js";import"./chunk-6UJXRT7F.js";import"./chunk-VIEK76DX.js";import w from"node:fs";import d from"node:path";import{spawn as N}from"node:child_process";import U from"node:net";import{WebSocket as O}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 O(`ws://localhost:${this.port}`),this.ready=new Promise((t,s)=>{let r=()=>{this.ws.off("error",o),t()},o=i=>{this.ws.off("open",r),s(new c(`could not connect to sootsim daemon on port ${this.port}: ${i.message}`,"NO_DAEMON"))};this.ws.once("open",r),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 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!==O.OPEN)throw new c("daemon connection is closed","NO_DAEMON");let s=this.nextId++;return new Promise((r,o)=>{let i=setTimeout(()=>{this.pending.delete(s),o(new c(`${e} timed out after ${Math.round(this.commandTimeoutMs/1e3)}s`,"TIMEOUT"))},this.commandTimeoutMs);this.pending.set(s,{resolve:r,reject:o,timer:i});try{this.ws.send(JSON.stringify({id:s,type:e,...t}))}catch(a){clearTimeout(i),this.pending.delete(s),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 r of this.eventListeners)try{r({sessionId:t.sessionId,event:t.event})}catch{}return}if(t.type==="agent:session-status"){for(let r of this.statusListeners)try{r(t.session)}catch{}return}if(typeof t.id!="number")return;let s=this.pending.get(t.id);s&&(this.pending.delete(t.id),clearTimeout(s.timer),t.error?s.reject(new c(t.error,t.code)):s.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 R(n=7668,e=400){return new Promise(t=>{let s=new U.Socket,r=!1,o=i=>{r||(r=!0,s.destroy(),t(i))};s.setTimeout(e),s.once("connect",()=>o(!0)),s.once("timeout",()=>o(!1)),s.once("error",()=>o(!1)),s.connect(n,"127.0.0.1")})}async function _(n={}){let e=n.port??7668;if(await R(e))return{alreadyRunning:!0};let{cmd:t,prefixArgs:s}=D(),r=[...s,"server","--quiet"];e!==7668&&r.push("--port",String(e));let o=N(t,r,{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 R(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 server\` manually to diagnose.`,"SPAWN_TIMEOUT")}async function h(n={}){await _({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 ue(n){let[e,...t]=n;try{switch(e){case void 0:case"--help":case"-h":case"help":return C(),0;case"attach":return await F(t);case"projects":return await B();case"project":return await W(t);case"sessions":return await J(t);case"start":return await V(t);case"prompt":return await q(t);case"watch":return await G(t);case"transcript":return await H(t);case"end":return await K(t);case"paths":return await z();default:return process.stderr.write(`unknown agent subcommand: ${e}
3
3
  `),C(),2}}catch(s){if(s instanceof c)return process.stderr.write(`${s.message}
4
4
  `),1;throw s}}async function v(n){let e=await h({clientLabel:"sootsim-agent-cli"});try{return await n(e)}finally{e.close()}}function C(){process.stdout.write(`sootsim agent \u2014 attached projects + local agent sessions
5
5
 
@@ -1,15 +1,15 @@
1
- /*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{b as M}from"./chunk-KAXZHEKM.js";import"./chunk-LHDWH7VS.js";import{execFile as q,spawn as L}from"node:child_process";import{randomUUID as X}from"node:crypto";import{constants as O,createReadStream as V,createWriteStream as j,existsSync as S,openSync as J}from"node:fs";import Y 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 G 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})})});G.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
- `)}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 R="never",F="danger-full-access",Z={type:"dangerFullAccess"},D="fast",ee="medium",te=Q(q);async function ne(d,t){let r=t||d;if(r.includes("/")||r.includes("\\"))return S(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 Se(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>
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{b as M}from"./chunk-IE2WYVJF.js";import"./chunk-VIEK76DX.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
+ `)}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>
6
6
  [--transcript <file>]
7
7
  [--codex-bin <path>] [--claude-bin <path>]
8
8
  `),2;if(t.provider!=="codex"&&t.provider!=="claude")return process.stderr.write(`unknown provider: ${t.provider}
9
- `),2;let{sessionId:r,projectId:m,cwd:u,promptIn:g,eventsOut:a}=t,c=t.provider;if(!S(a))return process.stderr.write(`events-out FIFO missing: ${a}
10
- `),3;if(!S(g))return process.stderr.write(`prompt-in FIFO missing: ${g}
11
- `),3;let n=J(a,O.O_RDWR|O.O_APPEND),s=j(a,{fd:n,flags:"a"});function i(o){let v=JSON.stringify({ts:Date.now(),...o})+`
12
- `;s.write(v)}let e=null;if(t.transcript)try{await Y.mkdir(z.dirname(t.transcript),{recursive:!0}),e=j(t.transcript,{flags:"a"})}catch(o){i({type:"error",message:`transcript open failed: ${o.message}`})}s.on("error",o=>{let v=`[events-out] stream error: ${o.message}
13
- `;try{e?e.write(v):process.stderr.write(v)}catch{}});let p=await ne(c,c==="codex"?t.codexBin:t.claudeBin);if(!p.ok)return i({type:"error",message:p.message}),await new Promise(o=>setTimeout(o,50)),s.end(),4;let f=p.path,l=null,x=null;if(c==="codex")try{l=W({bin:f,cwd:u,env:{SOOTSIM_SESSION_ID:r,SOOTSIM_PROJECT_ID:m}}),l.on("__stderr__",o=>{let v=o?.text;v&&e?.write(`[codex-stderr] ${v}`)}),l.exited.then(({code:o,signal:v})=>{h||(i({type:"error",message:`codex app-server exited (code=${o}, signal=${v??""})`}),w(5))}),await ce((async()=>{await l.request("initialize",{clientInfo:{name:"sootsim",title:null,version:"0.1.0"},capabilities:null}),x=await ie(l,u,{fresh:t.freshThread===!0})})(),3e4,"codex app-server boot timed out after 30s")}catch(o){let v=o instanceof Error?o.message:String(o);i({type:"error",message:`codex app-server init failed: ${v}`});try{l?.kill()}catch{}return s.end(),4}i({type:"ready",sessionId:r,projectId:m,provider:c,cwd:u});let T=!1,I=null,A=[],{promise:y,resolve:E}=$(),h=!1;function w(o){if(!h){h=!0,clearInterval(P);try{I?.kill("SIGTERM")}catch{}try{l?.shutdown(800)}catch{}i({type:"exited",code:o}),s.end(()=>{try{e?.end()}catch{}E(o)}),setTimeout(()=>E(o),1500).unref()}}let _=(()=>{let o=Number(process.env.SOOTSIM_WRAPPER_WATCHDOG_MS);return Number.isFinite(o)&&o>0?o:1e4})(),P=setInterval(()=>{h||(!S(a)||!S(g))&&(process.stderr.write(`[wrapper] session fifos gone (eventsOut=${S(a)} promptIn=${S(g)}), exiting
14
- `),w(0))},_);P.unref(),process.on("SIGTERM",()=>w(143)),process.on("SIGINT",()=>w(130)),process.on("SIGHUP",()=>w(129)),process.on("uncaughtException",o=>{i({type:"error",message:`uncaught: ${o.message}`}),w(1)});let B=c==="codex"&&l?oe({client:l,getThreadId:()=>x,setThreadId:o=>x=o,emit:i,transcript:e,onTurnSettled:()=>{T=!1;let o=A.shift();o&&k(o)}}):de({resolvedBin:f,sessionId:r,projectId:m,claudeSessionUuid:t.claudeSessionUuid??X(),cwd:u,emit:i,transcript:e,setChild:o=>I=o,onTurnSettled:()=>{T=!1;let o=A.shift();o&&k(o)}});async function k(o){T=!0;try{await B(o)}catch(v){i({type:"error",message:`turn failed: ${v.message}`}),T=!1;let C=A.shift();C&&k(C)}}let U=J(g,O.O_RDWR),N=V("",{fd:U,autoClose:!1});return K.createInterface({input:N,crlfDelay:1/0}).on("line",o=>{let v=M(o);if(!v)return;let C=v.text;if(i({type:"prompt-received",text:v.displayText??C,...v.inspectSummary?{inspectSummary:v.inspectSummary}:{},...v.inspectTrace?{inspectTrace:v.inspectTrace}:{}}),T){A.push(C);return}k(C)}),N.on("error",o=>{i({type:"error",message:`prompt-in read failed: ${o.message}`})}),y}function se(d){return d?.threadId??d?.thread?.id??null}async function ie(d,t,r={}){if(!r.fresh)try{let a=(await d.request("thread/list",{cwd:t,limit:1,archived:!1}))?.threads?.[0]?.id;if(a)try{return await d.request("thread/resume",{threadId:a,persistExtendedHistory:!1,approvalPolicy:R,sandbox:F,serviceTier:D}),a}catch{}}catch{}let m=await d.request("thread/start",{cwd:t,experimentalRawEvents:!1,persistExtendedHistory:!1,approvalPolicy:R,sandbox:F,serviceTier:D}),u=se(m);if(!u)throw new Error("thread/start returned no threadId");return u}function oe(d){let{client:t,emit:r,transcript:m}=d,u=new Map,g=null;return t.on("turn/started",a=>{let n=a?.turn?.id;if(!n)return;g=n;let s=u.get(n)??{started:Date.now(),resolve:()=>{},filesTouched:new Set,pendingEmit:""};u.has(n)||u.set(n,s),r({type:"turn-started",turnId:n})}),t.on("item/agentMessage/delta",a=>{let c=a;c?.delta&&(m?.write(c.delta),r({type:"turn-message",delta:c.delta}))}),t.on("item/reasoning/textDelta",a=>{let c=a;c?.delta&&r({type:"turn-reasoning",delta:c.delta})}),t.on("item/reasoning/summaryTextDelta",a=>{let c=a;c?.delta&&r({type:"turn-reasoning",delta:c.delta})}),t.on("turn/plan/updated",a=>{let c=a;Array.isArray(c?.plan)&&r({type:"turn-plan",steps:c.plan.map((n,s)=>({id:String(s),title:n.step,status:n.status}))})}),t.on("item/started",a=>{let n=a?.item;n&&(n.type==="commandExecution"&&n.command?r({type:"tool-call",name:"commandExecution",args:{command:n.command}}):(n.type==="mcpToolCall"||n.type==="dynamicToolCall")&&r({type:"tool-call",name:n.tool??n.type,args:{}}))}),t.on("item/completed",a=>{let c=a,n=c?.item;if(!n||n.type!=="fileChange"||n.status!=="completed"||!Array.isArray(n.changes))return;let s=c?.turnId,i=s?u.get(s):null;for(let e of n.changes){let p=e.kind?.type,f=p==="add"?"add":p==="delete"?"delete":"modify";r({type:"file-edited",path:e.path,kind:f,diff:e.diff}),i?.filesTouched.add(e.path);let l=e.kind?.move_path;l&&l!==e.path&&i?.filesTouched.add(l)}}),t.on("turn/completed",a=>{let c=a,n=c?.turn?.id;if(!n)return;let s=u.get(n),i=s?Array.from(s.filesTouched):[],e=c.turn?.durationMs??(s?Date.now()-s.started:0);r({type:"turn-completed",turnId:n,filesTouched:i,durationMs:e}),s?.resolve(),u.delete(n)}),t.on("error",a=>{let c=a,n=c?.error?.message??"codex reported an error";r({type:"error",message:n}),c.turnId&&(u.get(c.turnId)?.resolve(),u.delete(c.turnId))}),async function(c){let n=d.getThreadId();if(!n){r({type:"error",message:"no active codex thread"}),d.onTurnSettled();return}let{promise:s,resolve:i}=$(),e=`pending-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;u.set(e,{started:Date.now(),resolve:i,filesTouched:new Set,pendingEmit:""});try{let l=(await t.request("turn/start",{threadId:n,input:[{type:"text",text:c,text_elements:[]}],approvalPolicy:R,sandboxPolicy:Z,serviceTier:D,effort:ee}))?.turn?.id??g;if(l&&l!==e){let x=u.get(e);if(x){u.delete(e);let T=u.get(l);if(T){for(let I of x.filesTouched)T.filesTouched.add(I);T.resolve=x.resolve}else u.set(l,x)}}}catch(f){u.delete(e);let l=f instanceof Error?f.message:String(f);r({type:"error",message:`turn/start failed: ${l}`}),r({type:"turn-completed",filesTouched:[],durationMs:0}),d.onTurnSettled();return}let p=setTimeout(()=>i(),600*1e3).unref();try{await s}finally{clearTimeout(p),d.onTurnSettled()}}}var ae=new Set(["Edit","Write","MultiEdit","NotebookEdit"]);function de(d){return async function(r){let{resolvedBin:m,sessionId:u,projectId:g,claudeSessionUuid:a,cwd:c,emit:n,transcript:s,setChild:i}=d,e=Date.now();n({type:"turn-started"});let p=L(m,["--print","--output-format","stream-json","--verbose","--permission-mode","bypassPermissions","--session-id",a,r],{cwd:c,stdio:["ignore","pipe","pipe"],env:{...process.env,SOOTSIM_SESSION_ID:u,SOOTSIM_PROJECT_ID:g}});i(p);let f=new Set,l=!1;function x(y){let E=y.type;if(E){if(E==="assistant"&&Array.isArray(y.message?.content)){for(let h of y.message.content)if(h.type==="text"&&h.text)s?.write(h.text),n({type:"turn-message",delta:h.text});else if(h.type==="tool_use"&&h.name){n({type:"tool-call",name:h.name,args:h.input??{}});let w=h.input?.file_path??h.input?.path;typeof w=="string"&&ae.has(h.name)&&(f.add(w),n({type:"file-edited",path:w,kind:"modify"}))}}else if(E==="result"){if(l=!0,Array.isArray(y.permission_denials))for(let h of y.permission_denials)n({type:"approval-needed",kind:h.tool_name??"unknown",detail:h.tool_input??null});y.is_error&&typeof y.result=="string"&&n({type:"error",message:y.result}),n({type:"turn-completed",filesTouched:Array.from(f),durationMs:y.duration_ms??Date.now()-e,costUsd:y.is_error?void 0:y.total_cost_usd})}}}let T="";p.stdout?.setEncoding("utf8"),p.stdout?.on("data",y=>{T+=y;let E;for(;(E=T.indexOf(`
15
- `))>=0;){let h=T.slice(0,E);T=T.slice(E+1);let w=h.trim();if(!w)continue;let _;try{_=JSON.parse(w)}catch{continue}try{x(_)}catch(P){n({type:"error",message:`claude event handler failed: ${P.message}`})}}}),p.stderr?.setEncoding("utf8"),p.stderr?.on("data",y=>{s?.write(`[claude-stderr] ${y}`)}),p.on("error",y=>{n({type:"error",message:`spawn failed: ${y.message}`})});let{promise:I,resolve:A}=$();p.on("exit",y=>{l||(n({type:"turn-completed",filesTouched:Array.from(f),durationMs:Date.now()-e}),y!==0&&y!==null&&n({type:"error",message:`claude exited with code ${y}`})),i(null),A()});try{await I}finally{d.onTurnSettled()}}}function $(){let d;return{promise:new Promise(r=>{d=r}),resolve:d}}function ce(d,t,r){return new Promise((m,u)=>{let g=setTimeout(()=>u(new Error(r)),t);d.then(a=>{clearTimeout(g),m(a)},a=>{clearTimeout(g),u(a instanceof Error?a:new Error(String(a)))})})}export{se as extractCodexThreadId,Se as runAgentWrapper};
9
+ `),2;let{sessionId:r,projectId:m,cwd:u,promptIn:g,eventsOut:a}=t,c=t.provider;if(!I(a))return process.stderr.write(`events-out FIFO missing: ${a}
10
+ `),3;if(!I(g))return process.stderr.write(`prompt-in FIFO missing: ${g}
11
+ `),3;let n=J(a,R.O_RDWR|R.O_APPEND),s=j(a,{fd:n,flags:"a"});function i(o){let v=JSON.stringify({ts:Date.now(),...o})+`
12
+ `;s.write(v)}let e=null;if(t.transcript)try{await V.mkdir(z.dirname(t.transcript),{recursive:!0}),e=j(t.transcript,{flags:"a"})}catch(o){i({type:"error",message:`transcript open failed: ${o.message}`})}s.on("error",o=>{let v=`[events-out] stream error: ${o.message}
13
+ `;try{e?e.write(v):process.stderr.write(v)}catch{}});let p=await ne(c,c==="codex"?t.codexBin:t.claudeBin);if(!p.ok)return i({type:"error",message:p.message}),await new Promise(o=>setTimeout(o,50)),s.end(),4;let f=p.path,l=null,x=null;if(c==="codex")try{l=W({bin:f,cwd:u,env:{SOOTSIM_CLI_IDENTITY:r,SOOTSIM_PROJECT_ID:m}}),l.on("__stderr__",o=>{let v=o?.text;v&&e?.write(`[codex-stderr] ${v}`)}),l.exited.then(({code:o,signal:v})=>{h||(i({type:"error",message:`codex app-server exited (code=${o}, signal=${v??""})`}),w(5))}),await ce((async()=>{await l.request("initialize",{clientInfo:{name:"sootsim",title:null,version:"0.1.0"},capabilities:null}),x=await ie(l,u,{fresh:t.freshThread===!0})})(),3e4,"codex app-server boot timed out after 30s")}catch(o){let v=o instanceof Error?o.message:String(o);i({type:"error",message:`codex app-server init failed: ${v}`});try{l?.kill()}catch{}return s.end(),4}i({type:"ready",sessionId:r,projectId:m,provider:c,cwd:u});let T=!1,S=null,A=[],{promise:y,resolve:E}=$(),h=!1;function w(o){if(!h){h=!0,clearInterval(P);try{S?.kill("SIGTERM")}catch{}try{l?.shutdown(800)}catch{}i({type:"exited",code:o}),s.end(()=>{try{e?.end()}catch{}E(o)}),setTimeout(()=>E(o),1500).unref()}}let _=(()=>{let o=Number(process.env.SOOTSIM_WRAPPER_WATCHDOG_MS);return Number.isFinite(o)&&o>0?o:1e4})(),P=setInterval(()=>{h||(!I(a)||!I(g))&&(process.stderr.write(`[wrapper] session fifos gone (eventsOut=${I(a)} promptIn=${I(g)}), exiting
14
+ `),w(0))},_);P.unref(),process.on("SIGTERM",()=>w(143)),process.on("SIGINT",()=>w(130)),process.on("SIGHUP",()=>w(129)),process.on("uncaughtException",o=>{i({type:"error",message:`uncaught: ${o.message}`}),w(1)});let B=c==="codex"&&l?oe({client:l,getThreadId:()=>x,setThreadId:o=>x=o,emit:i,transcript:e,onTurnSettled:()=>{T=!1;let o=A.shift();o&&k(o)}}):de({resolvedBin:f,sessionId:r,projectId:m,claudeSessionUuid:t.claudeSessionUuid??X(),cwd:u,emit:i,transcript:e,setChild:o=>S=o,onTurnSettled:()=>{T=!1;let o=A.shift();o&&k(o)}});async function k(o){T=!0;try{await B(o)}catch(v){i({type:"error",message:`turn failed: ${v.message}`}),T=!1;let C=A.shift();C&&k(C)}}let U=J(g,R.O_RDWR),N=Y("",{fd:U,autoClose:!1});return K.createInterface({input:N,crlfDelay:1/0}).on("line",o=>{let v=M(o);if(!v)return;let C=v.text;if(i({type:"prompt-received",text:v.displayText??C,...v.inspectSummary?{inspectSummary:v.inspectSummary}:{},...v.inspectTrace?{inspectTrace:v.inspectTrace}:{}}),T){A.push(C);return}k(C)}),N.on("error",o=>{i({type:"error",message:`prompt-in read failed: ${o.message}`})}),y}function se(d){return d?.threadId??d?.thread?.id??null}async function ie(d,t,r={}){if(!r.fresh)try{let a=(await d.request("thread/list",{cwd:t,limit:1,archived:!1}))?.threads?.[0]?.id;if(a)try{return await d.request("thread/resume",{threadId:a,persistExtendedHistory:!1,approvalPolicy:O,sandbox:F,serviceTier:D}),a}catch{}}catch{}let m=await d.request("thread/start",{cwd:t,experimentalRawEvents:!1,persistExtendedHistory:!1,approvalPolicy:O,sandbox:F,serviceTier:D}),u=se(m);if(!u)throw new Error("thread/start returned no threadId");return u}function oe(d){let{client:t,emit:r,transcript:m}=d,u=new Map,g=null;return t.on("turn/started",a=>{let n=a?.turn?.id;if(!n)return;g=n;let s=u.get(n)??{started:Date.now(),resolve:()=>{},filesTouched:new Set,pendingEmit:""};u.has(n)||u.set(n,s),r({type:"turn-started",turnId:n})}),t.on("item/agentMessage/delta",a=>{let c=a;c?.delta&&(m?.write(c.delta),r({type:"turn-message",delta:c.delta}))}),t.on("item/reasoning/textDelta",a=>{let c=a;c?.delta&&r({type:"turn-reasoning",delta:c.delta})}),t.on("item/reasoning/summaryTextDelta",a=>{let c=a;c?.delta&&r({type:"turn-reasoning",delta:c.delta})}),t.on("turn/plan/updated",a=>{let c=a;Array.isArray(c?.plan)&&r({type:"turn-plan",steps:c.plan.map((n,s)=>({id:String(s),title:n.step,status:n.status}))})}),t.on("item/started",a=>{let n=a?.item;n&&(n.type==="commandExecution"&&n.command?r({type:"tool-call",name:"commandExecution",args:{command:n.command}}):(n.type==="mcpToolCall"||n.type==="dynamicToolCall")&&r({type:"tool-call",name:n.tool??n.type,args:{}}))}),t.on("item/completed",a=>{let c=a,n=c?.item;if(!n||n.type!=="fileChange"||n.status!=="completed"||!Array.isArray(n.changes))return;let s=c?.turnId,i=s?u.get(s):null;for(let e of n.changes){let p=e.kind?.type,f=p==="add"?"add":p==="delete"?"delete":"modify";r({type:"file-edited",path:e.path,kind:f,diff:e.diff}),i?.filesTouched.add(e.path);let l=e.kind?.move_path;l&&l!==e.path&&i?.filesTouched.add(l)}}),t.on("turn/completed",a=>{let c=a,n=c?.turn?.id;if(!n)return;let s=u.get(n),i=s?Array.from(s.filesTouched):[],e=c.turn?.durationMs??(s?Date.now()-s.started:0);r({type:"turn-completed",turnId:n,filesTouched:i,durationMs:e}),s?.resolve(),u.delete(n)}),t.on("error",a=>{let c=a,n=c?.error?.message??"codex reported an error";r({type:"error",message:n}),c.turnId&&(u.get(c.turnId)?.resolve(),u.delete(c.turnId))}),async function(c){let n=d.getThreadId();if(!n){r({type:"error",message:"no active codex thread"}),d.onTurnSettled();return}let{promise:s,resolve:i}=$(),e=`pending-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;u.set(e,{started:Date.now(),resolve:i,filesTouched:new Set,pendingEmit:""});try{let l=(await t.request("turn/start",{threadId:n,input:[{type:"text",text:c,text_elements:[]}],approvalPolicy:O,sandboxPolicy:Z,serviceTier:D,effort:ee}))?.turn?.id??g;if(l&&l!==e){let x=u.get(e);if(x){u.delete(e);let T=u.get(l);if(T){for(let S of x.filesTouched)T.filesTouched.add(S);T.resolve=x.resolve}else u.set(l,x)}}}catch(f){u.delete(e);let l=f instanceof Error?f.message:String(f);r({type:"error",message:`turn/start failed: ${l}`}),r({type:"turn-completed",filesTouched:[],durationMs:0}),d.onTurnSettled();return}let p=setTimeout(()=>i(),600*1e3).unref();try{await s}finally{clearTimeout(p),d.onTurnSettled()}}}var ae=new Set(["Edit","Write","MultiEdit","NotebookEdit"]);function de(d){return async function(r){let{resolvedBin:m,sessionId:u,projectId:g,claudeSessionUuid:a,cwd:c,emit:n,transcript:s,setChild:i}=d,e=Date.now();n({type:"turn-started"});let p=q(m,["--print","--output-format","stream-json","--verbose","--permission-mode","bypassPermissions","--session-id",a,r],{cwd:c,stdio:["ignore","pipe","pipe"],env:{...process.env,SOOTSIM_CLI_IDENTITY:u,SOOTSIM_PROJECT_ID:g}});i(p);let f=new Set,l=!1;function x(y){let E=y.type;if(E){if(E==="assistant"&&Array.isArray(y.message?.content)){for(let h of y.message.content)if(h.type==="text"&&h.text)s?.write(h.text),n({type:"turn-message",delta:h.text});else if(h.type==="tool_use"&&h.name){n({type:"tool-call",name:h.name,args:h.input??{}});let w=h.input?.file_path??h.input?.path;typeof w=="string"&&ae.has(h.name)&&(f.add(w),n({type:"file-edited",path:w,kind:"modify"}))}}else if(E==="result"){if(l=!0,Array.isArray(y.permission_denials))for(let h of y.permission_denials)n({type:"approval-needed",kind:h.tool_name??"unknown",detail:h.tool_input??null});y.is_error&&typeof y.result=="string"&&n({type:"error",message:y.result}),n({type:"turn-completed",filesTouched:Array.from(f),durationMs:y.duration_ms??Date.now()-e,costUsd:y.is_error?void 0:y.total_cost_usd})}}}let T="";p.stdout?.setEncoding("utf8"),p.stdout?.on("data",y=>{T+=y;let E;for(;(E=T.indexOf(`
15
+ `))>=0;){let h=T.slice(0,E);T=T.slice(E+1);let w=h.trim();if(!w)continue;let _;try{_=JSON.parse(w)}catch{continue}try{x(_)}catch(P){n({type:"error",message:`claude event handler failed: ${P.message}`})}}}),p.stderr?.setEncoding("utf8"),p.stderr?.on("data",y=>{s?.write(`[claude-stderr] ${y}`)}),p.on("error",y=>{n({type:"error",message:`spawn failed: ${y.message}`})});let{promise:S,resolve:A}=$();p.on("exit",y=>{l||(n({type:"turn-completed",filesTouched:Array.from(f),durationMs:Date.now()-e}),y!==0&&y!==null&&n({type:"error",message:`claude exited with code ${y}`})),i(null),A()});try{await S}finally{d.onTurnSettled()}}}function $(){let d;return{promise:new Promise(r=>{d=r}),resolve:d}}function ce(d,t,r){return new Promise((m,u)=>{let g=setTimeout(()=>u(new Error(r)),t);d.then(a=>{clearTimeout(g),m(a)},a=>{clearTimeout(g),u(a instanceof Error?a:new Error(String(a)))})})}export{se as extractCodexThreadId,Ie as runAgentWrapper};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import"./chunk-LHDWH7VS.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.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import"./chunk-VIEK76DX.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(", ")}
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a,b,c,d}from"./chunk-5HNZO5AI.js";import"./chunk-TR554AIH.js";import"./chunk-2ABGQIW7.js";import"./chunk-23YMXBQ2.js";import"./chunk-6UJXRT7F.js";import"./chunk-VIEK76DX.js";export{c as ensureDaemonRunning,a as ensureRuntimeInstalled,d as ensureSootsimReady,b as resolveBootstrapPort};
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a,b,c,d,e}from"./chunk-IKVIHHWE.js";import"./chunk-VIEK76DX.js";export{e as BETA_ASK_HEADLINE,c as BETA_LABEL,d as BETA_TAGLINE,b as BETA_VERSION_TARGET,a as IS_BETA};
@@ -0,0 +1 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -0,0 +1,4 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{existsSync as C,mkdirSync as D,readFileSync as O,rmSync as s,writeFileSync as g}from"fs";import{tmpdir as P}from"os";import{dirname as R,join as A,resolve as x}from"path";import{execFileSync as a}from"child_process";import{readFileSync as I}from"fs";import{createRequire as S}from"module";var o=null;function u(r){o||(o=_());try{return o(r)}catch{return null}}function _(){let r=Number(process.env.PPID);if(Number.isFinite(r)&&r>1&&r!==process.ppid)return()=>r;if(process.platform==="linux")return y();if(process.platform==="darwin"){let n=E();return n||T()}return()=>null}function y(){return r=>{try{let n=I(`/proc/${r}/stat`,"utf8"),t=n.lastIndexOf(")");if(t<0)return null;let i=n.slice(t+1).trim().split(/\s+/),e=Number(i[1]);return Number.isFinite(e)&&e>0?e:null}catch{return null}}}var N=3,d=216,b=16;function E(){if(!process.versions?.bun)return null;try{let r=S(import.meta.url),{dlopen:n,FFIType:t}=r("bun:ffi"),i=n("/usr/lib/libproc.dylib",{proc_pidinfo:{args:[t.i32,t.i32,t.u64,t.ptr,t.i32],returns:t.i32}}),e=Buffer.alloc(d);return m=>{if(Number(i.symbols.proc_pidinfo(m,N,0n,e,d))<=0)return null;let p=e.readUInt32LE(b);return p>0?p:null}}catch{return null}}function T(){return r=>{try{let t=a("lsof",["-R","-p",String(r),"-d","cwd","-a"],{encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).split(`
3
+ `)[1];if(!t)return null;let i=t.trim().split(/\s+/),e=Number(i[2]);return Number.isFinite(e)&&e>1?e:null}catch{return null}}}var c=1,f="SOOTSIM_CLI_CURRENT_SIM_PATH",v=["SOOTSIM_CLI_IDENTITY","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","TERM_SESSION_ID","ITERM_SESSION_ID","TMUX_PANE","STY","KITTY_WINDOW_ID","WEZTERM_PANE","ALACRITTY_WINDOW_ID","WINDOWID","VSCODE_INJECTION"];function F(r,n=20){let t=u(r);if(!t||t<=1)return null;for(let i=0;i<n;i++){let e=u(t);if(!e||e<=1)return t;t=e}return t}function k(){for(let n of v){let t=process.env[n];if(t&&t.trim())return{key:`${n}:${t.trim()}`,source:n,stable:!0}}let r=F(process.ppid);return r&&r>1?{key:`gppid-${r}`,source:"grand-ppid",stable:!0}:{key:`pid-${process.ppid}`,source:"ppid",stable:!1}}function L(){return k().key}function l(){if(process.env[f])return x(process.env[f]);let r=L();return A(P(),`sootsim-current-sim-${r}.json`)}function h(){let r=l();if(!C(r))return null;try{let n=JSON.parse(O(r,"utf8"));return n.version!==c||typeof n.simId!="string"||!n.simId.trim()||typeof n.updatedAt!="string"?(s(r,{force:!0}),null):{version:c,simId:n.simId.trim(),updatedAt:n.updatedAt}}catch{return s(r,{force:!0}),null}}function J(){return h()?.simId||null}function j(r){let n=r.trim();if(!n)return;let t=l();D(R(t),{recursive:!0}),g(t,JSON.stringify({version:c,simId:n,updatedAt:new Date().toISOString()},null,2)+`
4
+ `)}function K(){s(l(),{force:!0})}export{k as a,L as b,J as c,j as d,K as e};
@@ -0,0 +1,7 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as l}from"./chunk-TR554AIH.js";import{E as u,F as c,g as p,i as h,z as w}from"./chunk-6UJXRT7F.js";import{closeSync as v,existsSync as f,openSync as P,readSync as S,statSync as g}from"fs";import{homedir as k}from"os";import{resolve as T}from"path";import{WebSocket as D}from"ws";var E=6e4;async function L(){let t=w();if(t&&f(h(t)))return;console.log(" first run \u2014 installing sootsim engine runtime (~6 MB)...");let{runRuntime:e}=await import("./runtime-GFWS3QLZ.js");await e(["install"],{})}function I(t,e){return x(t)??e??l()}async function $(t=l(),e=E){if(await m(t,250))return;let n=u();if(n&&c(n)){if(n.bootstrapping===!0&&(await b(e),await m(n.bridgePort,500)))return;throw new Error(`sootsim daemon lockfile is fresh (port ${n.bridgePort}) but the bridge is not reachable. run \`sootsim daemon restart\` or \`sootsim daemon uninstall\`.`)}if(p())throw new Error(`sootsim bridge daemon is not running on port ${t}.
3
+ dev checkouts skip the auto-install of the persistent launchd / systemd
4
+ agent. start the daemon manually in another shell with:
5
+ bun sootsim server
6
+ (set SOOTSIM_FORCE_DAEMON_INSTALL=1 to allow auto-install from this repo.)`);console.log(" registering sootsim bridge daemon...");let{daemonInstall:o}=await import("./daemon-2Z4DAJT6.js");try{await o({port:t,force:!0})}catch(r){let s=r instanceof Error?r.message:String(r);throw new Error(`${s}
7
+ if this keeps failing, run \`sootsim daemon uninstall\` and retry, or run \`sootsim server\` in a persistent shell as a workaround.`)}console.log(" waiting for runtime to come online...");let i=process.platform==="darwin"?B():null;try{await b(e);let r=Date.now()+5e3;for(;Date.now()<r;){if(await m(t,500))return;await new Promise(s=>setTimeout(s,200))}throw new Error(`daemon registered but the bridge never bound on port ${t} \u2014 see ${d()} (mac) or \`journalctl --user -u sootsim-server\` (linux).`)}finally{i?.stop()}}async function C(t=l()){await L(),await $(t)}function x(t){for(let e=0;e<t.length;e++){let n=t[e];if((n==="--port"||n==="-p")&&t[e+1]){let o=Number(t[e+1]);return Number.isFinite(o)?o:void 0}if(n.startsWith("--port=")){let o=Number(n.slice(7));return Number.isFinite(o)?o:void 0}}}function m(t,e){return new Promise(n=>{let o=new D(`ws://127.0.0.1:${t}`,{handshakeTimeout:e}),i=!1,r=s=>{if(!i){i=!0;try{o.close()}catch{}n(s)}};o.once("open",()=>r(!0)),o.once("error",()=>r(!1)),setTimeout(()=>r(!1),e)})}async function b(t){let e=Date.now()+t,n;for(;Date.now()<e;){let o=u();if(o&&c(o)){if(o.bootstrapping!==!0)return;o.bootstrapping!==n&&(n=o.bootstrapping)}await new Promise(i=>setTimeout(i,250))}throw new Error(`daemon did not finish bootstrapping within ${Math.round(t/1e3)}s \u2014 check ${d()} (mac) or \`journalctl --user -u sootsim-server\` (linux).`)}function d(){return T(k(),"Library/Logs/sootsim/server.err.log")}function B(){let t=d(),e=0;try{f(t)&&(e=g(t).size)}catch{}let n=!1,o=()=>{if(!n){try{if(f(t)){let i=g(t).size;if(i>e){let r=Buffer.alloc(i-e),s=P(t,"r");try{S(s,r,0,r.length,e)}finally{v(s)}e=i;for(let y of r.toString("utf8").split(/\r?\n/)){let a=y.trim();a&&(a.startsWith("sootsim:")||a.startsWith("sootsim "))&&console.log(` ${a}`)}}else i<e&&(e=i)}}catch{}setTimeout(o,250)}};return o(),{stop:()=>{n=!0}}}export{L as a,I as b,$ as c,C as d};
@@ -0,0 +1,3 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{l as P,n as a,y as m}from"./chunk-6UJXRT7F.js";import l from"fs";import c from"path";var s="default",S="profiles.json",i=1;function o(e){let r=e.trim();if(!r)throw new Error("profile id is required");if(!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(r))throw new Error("profile ids must start with a letter or number and contain only letters, numbers, dot, dash, or underscore");if(r==="."||r==="..")throw new Error(`invalid profile id: ${r}`);return r}function d(){return c.join(a(),S)}function I(e){return`sootsim-profile-${o(e)}`}function h(e){return c.join(P(),"Partitions",I(e))}function A(e){return c.join(a(),"playwright",o(e))}function u(){try{let e=JSON.parse(l.readFileSync(d(),"utf8"));if(!e||e.version!==i)return{version:i,profiles:[]};let r=Array.isArray(e.profiles)?e.profiles.filter(t=>!!t&&typeof t.id=="string"&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string").map(t=>({id:o(t.id),createdAt:t.createdAt,updatedAt:t.updatedAt})):[];return{version:i,profiles:r}}catch{return{version:i,profiles:[]}}}function x(e){return[...e].sort((r,t)=>r.id===s?-1:t.id===s?1:r.id.localeCompare(t.id))}function p(e){if(e.profiles.some(t=>t.id===s))return{...e,profiles:x(e.profiles)};let r=new Date().toISOString();return{version:i,profiles:x([{id:s,createdAt:r,updatedAt:r},...e.profiles])}}function g(e){m();let r=p(e),t=`${d()}.tmp`;return l.writeFileSync(t,`${JSON.stringify(r,null,2)}
3
+ `,"utf8"),l.renameSync(t,d()),r}function y(){return g(u()).profiles}function E(e){let r=o(e);return y().find(t=>t.id===r)??null}function _(e=s){let r=o(e),t=E(r);return t||D(r)}function D(e){let r=o(e),t=p(u());if(t.profiles.some(w=>w.id===r))throw new Error(`profile already exists: ${r}`);let f=new Date().toISOString(),n={id:r,createdAt:f,updatedAt:f};return g({version:i,profiles:[...t.profiles,n]}),n}function F(e){let r=o(e);if(r===s)throw new Error("the default profile cannot be deleted; clear it instead");let t=p(u()),f=t.profiles.find(n=>n.id===r);if(!f)throw new Error(`profile not found: ${r}`);return g({version:i,profiles:t.profiles.filter(n=>n.id!==r)}),v(r),f}function v(e){let r=o(e);for(let t of[h(r),A(r)])try{l.rmSync(t,{recursive:!0,force:!0})}catch{}}export{A as a,y as b,_ as c,D as d,F as e,v as f};
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as o}from"./chunk-EJLNUMMP.js";import{o as s}from"./chunk-5QIUJNT3.js";function u(){let e=process.env.DO_NOT_TRACK;return e==="1"||e==="true"||!s()}function a(){if(u())return null;let e=process.env.SOOT_POSTHOG_API_KEY||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 c(e){return e?e.userId?e.userId:e.installationId!=null?`install:${e.installationId}`:e.repoId?`repo:${e.repoId}`:e.shareId?`share:${e.shareId}`:"anonymous-cli":"anonymous-cli"}function p(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:c(t),properties:n,timestamp:new Date().toISOString()}}var r=[],l=!1;async function i(){if(r.length===0)return;let e=a();if(!e){r.length=0;return}let t=r.splice(0,r.length).map(p);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 d(){l||(l=!0,process.on("beforeExit",()=>{i()}),process.on("exit",()=>{i()}))}function h(e){if(u())return;d();let t=null;try{t=o()?.user?.id??null}catch{t=null}r.push({...e,identity:{source:"cli",userId:t,...e.identity}})}async function g(){await i()}export{h as a,g as b};
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as s}from"./chunk-BEY2QVU5.js";import{w as o}from"./chunk-6UJXRT7F.js";function u(){let e=process.env.DO_NOT_TRACK;return e==="1"||e==="true"||!o()}function a(){if(u())return null;let e=process.env.SOOT_POSTHOG_API_KEY||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 c(e){return e?e.userId?e.userId:e.installationId!=null?`install:${e.installationId}`:e.repoId?`repo:${e.repoId}`:e.shareId?`share:${e.shareId}`:"anonymous-cli":"anonymous-cli"}function p(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:c(t),properties:n,timestamp:new Date().toISOString()}}var r=[],l=!1;async function i(){if(r.length===0)return;let e=a();if(!e){r.length=0;return}let t=r.splice(0,r.length).map(p);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 d(){l||(l=!0,process.on("beforeExit",()=>{i()}),process.on("exit",()=>{i()}))}function h(e){if(u())return;d();let t=null;try{t=s()?.user?.id??null}catch{t=null}r.push({...e,identity:{source:"cli",userId:t,...e.identity}})}async function g(){await i()}export{h as a,g as b};
@@ -0,0 +1,5 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import r from"node:fs";import{homedir as O}from"node:os";import n from"node:path";var L="SOOTSIM_HOME",E="active",A="daemon.json",j="config.json",I=3e4;function c(){let e=process.env[L];return e&&e.length>0?n.resolve(e):n.join(O(),".sootsim")}function K(){if(process.env.SOOTSIM_FORCE_DAEMON_INSTALL==="1")return!1;let e=process.env.SOOTSIM_DEV;if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;let t=process.argv[1];if(!t)return!1;try{return r.realpathSync(t).includes(`${n.sep}packages${n.sep}sootsim${n.sep}`)}catch{return!1}}function f(){return n.join(c(),"runtimes")}function _(e){return n.join(f(),e)}function D(){return n.join(f(),E)}function S(){return n.join(c(),"electron")}function U(){return n.join(S(),"userData")}function Y(e){return n.join(S(),e)}function N(){return n.join(c(),"profiles")}function F(){return n.join(c(),"daemon-app")}function T(){return n.join(F(),"SootSim Daemon.app")}function G(){return n.join(T(),"Contents","MacOS","sootsim-daemon")}function C(){return n.join(c(),"cache")}function p(){return n.join(c(),A)}function d(){return n.join(c(),j)}function v(){try{let e=r.readFileSync(d(),"utf8"),t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}function M(e){y();let t=v(),s={...t,...e};e.settings&&typeof e.settings=="object"&&(s.settings={...t.settings&&typeof t.settings=="object"?t.settings:{},...e.settings});let u=`${d()}.tmp`;return r.writeFileSync(u,`${JSON.stringify(s,null,2)}
3
+ `,"utf8"),r.renameSync(u,d()),s}function X(){return v().telemetry!==!1}function q(e){M({telemetry:e})}function y(){r.mkdirSync(c(),{recursive:!0}),r.mkdirSync(f(),{recursive:!0}),r.mkdirSync(S(),{recursive:!0}),r.mkdirSync(N(),{recursive:!0}),r.mkdirSync(C(),{recursive:!0})}function w(){try{let e=r.readFileSync(D(),"utf8").trim();return e.length>0?e:null}catch{return null}}function z(e){r.mkdirSync(f(),{recursive:!0}),r.writeFileSync(D(),`${e}
4
+ `,"utf8")}function Q(){try{return r.readdirSync(f(),{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name).sort(P)}catch{return[]}}function P(e,t){let s=i=>{let a=i.indexOf("-"),l=a>=0?i.slice(0,a):i,k=a>=0?i.slice(a+1):"",b=l.split(".").map(g=>Number.parseInt(g,10));return b.some(g=>!Number.isFinite(g))?[[Number.POSITIVE_INFINITY],i]:[b,k]},[u,o]=s(e),[x,m]=s(t);for(let i=0;i<Math.max(u.length,x.length);i++){let a=u[i]??0,l=x[i]??0;if(a!==l)return a-l}return o===m?0:o?m?o<m?-1:1:-1:1}function W(){let e=w();if(!e)return null;let t=_(e);try{if(r.statSync(t).isDirectory())return t}catch{}return null}var h=16*1024;function R(){try{let e=r.openSync(p(),"r");try{let t=Buffer.alloc(h),s=r.readSync(e,t,0,h,0),u=t.subarray(0,s).toString("utf8"),o=JSON.parse(u);return o&&o.schema===1&&typeof o.pid=="number"&&typeof o.bridgePort=="number"&&typeof o.runtimePort=="number"&&typeof o.startedAt=="number"&&typeof o.heartbeatAt=="number"?o:null}finally{r.closeSync(e)}}catch{return null}}function $(e,t=Date.now()){if(!e||t-e.heartbeatAt>I)return!1;try{return process.kill(e.pid,0),!0}catch{return!1}}function H(e){y();let t=`${p()}.tmp`;r.writeFileSync(t,`${JSON.stringify(e,null,2)}
5
+ `,"utf8"),r.renameSync(t,p())}function Z(e){y();let t=R();return t&&$(t)&&t.pid!==e.pid?!1:(H(e),!0)}function ee(){try{r.unlinkSync(p())}catch{}}export{L as a,E as b,A as c,j as d,I as e,c as f,K as g,f as h,_ as i,D as j,S as k,U as l,Y as m,N as n,F as o,T as p,G as q,C as r,p as s,d as t,v as u,M as v,X as w,q as x,y,w as z,z as A,Q as B,P as C,W as D,R as E,$ as F,H as G,Z as H,ee as I};
@@ -0,0 +1,66 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{d as Q,e as X}from"./chunk-UD5ILFN5.js";import{a as D,b}from"./chunk-67K3WAEZ.js";import{a as K}from"./chunk-BEY2QVU5.js";import{d as J}from"./chunk-G23GIRBM.js";import{c as q,e as Y,g as w}from"./chunk-TR554AIH.js";import{createHash as Te}from"crypto";import{readFileSync as te}from"fs";import{gzipSync as ne}from"zlib";function Z(e){let t=(e||"").toLowerCase().split(";")[0].trim();return t?!(t.startsWith("image/")||t.startsWith("video/")||t.startsWith("audio/")||t==="font/woff2"||t==="application/font-woff2"||t==="application/zip"||t==="application/gzip"):!0}function H(e,t){let r=new AbortController,s=setTimeout(()=>r.abort(new Error(`${t} timed out after ${e/1e3}s`)),e);return{signal:r.signal,cancel:()=>clearTimeout(s)}}async function be(e){let t=H(12e4,`PUT ${e.url}`),r;try{r=await fetch(e.url,{method:"PUT",headers:{"content-type":e.contentType},body:e.bytes,signal:t.signal})}finally{t.cancel()}if(!r.ok){let s=await r.text().catch(()=>"");throw new Error(`PUT ${r.status}: ${s.slice(0,200)}`)}}async function we(e,t=8,r){let s=0,o=0,a=e.length;await Promise.all(Array.from({length:Math.min(t,a)},async()=>{for(;s<a;){let u=e[s++];await be(u),o++,r?.(o,a)}}))}function ve(e,t,r,s){let o=[];o.push({url:e.bundle.putUrl,contentType:e.bundle.contentType,bytes:t});for(let a of e.files){let u=r.get(a.urlhash);u&&o.push({url:a.putUrl,contentType:a.contentType,bytes:u})}return e.events&&s?.eventsBytes&&o.push({url:e.events.putUrl,contentType:e.events.contentType,bytes:s.eventsBytes}),e.flowVideo&&s?.videoBytes&&o.push({url:e.flowVideo.putUrl,contentType:e.flowVideo.contentType,bytes:s.videoBytes}),e.storage&&s?.storageBytes&&o.push({url:e.storage.putUrl,contentType:e.storage.contentType,bytes:s.storageBytes}),o}function Be(e){return e.replace(/\/+$/,"")}var _=class extends Error{constructor(r,s,o){super(r);this.status=s;this.phase=o;this.name="PresignedUploadError"}};async function ee(e){let t=Be(e.originBase),r={"content-type":"application/json"};e.authHeader&&(r.authorization=e.authHeader),e.adminBypassToken&&(r["x-soot-admin-upload-bypass"]=e.adminBypassToken);let s=H(3e4,"init"),o;try{o=await fetch(`${t}/api/preview/upload/init`,{method:"POST",headers:r,body:JSON.stringify(e.initBody),signal:s.signal})}finally{s.cancel()}if(!o.ok){let B=await o.text().catch(()=>"");throw new _(`init failed: ${o.status} ${B.slice(0,200)}`,o.status,"init")}let a=await o.json(),u=ve(a,e.bundleBytes,e.filesByHash,e.extras);await we(u,e.concurrency??8,e.onPutProgress);let y=H(3e4,"finalize"),p;try{p=await fetch(`${t}/api/preview/upload/finalize`,{method:"POST",headers:r,body:JSON.stringify({token:a.token}),signal:y.signal})}finally{y.cancel()}if(!p.ok){let B=await p.text().catch(()=>"");throw new _(`finalize failed: ${p.status} ${B.slice(0,200)}`,p.status,"finalize")}let P=await p.json();return{init:a,finalize:P}}var ie=process.env.SOOTSIM_UPLOAD_ORIGIN||"https://sootbean.com",ae=process.env.SOOTSIM_PREVIEW_ORIGIN||"https://sootsim.com",M="http://localhost:3000";async function Ie(e){if(e)return e;if(process.env.SOOTSIM_UPLOAD_ORIGIN)return process.env.SOOTSIM_UPLOAD_ORIGIN;try{let t=await fetch(`${M}/api/preview/upload/init`,{method:"OPTIONS"});if(t.ok||t.status===204||t.status===405)return M}catch{}return ie}function v(e){return e.replace(/\/$/,"")}function Ue(e){try{let r=new URL(e).hostname.replace(/^\[|\]$/g,"").toLowerCase();return r==="localhost"||r.endsWith(".localhost")||r==="0.0.0.0"||r==="::1"||/^127(?:\.\d{1,3}){3}$/.test(r)}catch{return!1}}function Pe(e){try{let t=new URL(e).hostname.toLowerCase();return t==="sootbean.com"||t.endsWith(".sootbean.com")}catch{return!1}}function Se(e,t){return t?v(t):process.env.SOOTSIM_PREVIEW_ORIGIN?v(process.env.SOOTSIM_PREVIEW_ORIGIN):Ue(e)?v(e):Pe(e)?v(ae):v(e)}function xe(){console.log(`
3
+ sootsim upload \u2014 publish the current bundle as a /preview/<id> link
4
+
5
+ usage:
6
+ sootsim upload [--origin <url>] [--public-origin <url>] [--events <path>] [--sim <sim>] [--open] [--assets-only]
7
+
8
+ options:
9
+ --origin <url> upload target (default: auto)
10
+ prefers ${M} when available, otherwise
11
+ falls back to ${ie}
12
+ override with SOOTSIM_UPLOAD_ORIGIN env var
13
+ --public-origin <url>
14
+ public /preview link origin (default: ${ae}
15
+ for prod uploads, upload origin for localhost/custom origins).
16
+ override with SOOTSIM_PREVIEW_ORIGIN env var
17
+ --events <path> path to a gzipped events .jsonl.gz file to attach
18
+ --video <path> path to a webm/mp4/gif flow recording. embedded inline
19
+ in the pr sticky comment served at
20
+ /api/preview/flow-video?id=<share-id>
21
+ --video-duration-ms <ms>
22
+ duration hint for attached flow video
23
+ --sim <sim> target a specific sim (see: sootsim list)
24
+ --open open the resulting /preview/<id> url in the browser
25
+ --assets-only drop API/JSON/HTML records before upload; keep images,
26
+ fonts, css, js, and binary blobs. live-data demos hit
27
+ the real network at replay time instead of serving
28
+ recorded API snapshots
29
+ -h, --help
30
+
31
+ examples:
32
+ sootsim upload
33
+ sootsim upload --origin http://localhost:3000 --open
34
+ sootsim upload --events ./my-session.jsonl.gz
35
+ sootsim upload --video /tmp/soot-flow.webm
36
+ `)}function U(e,t){let r=e.findIndex(o=>o===t);if(r<0)return;let s=e[r+1];return e.splice(r,2),s}function re(e,t){let r=e.findIndex(s=>s===t);return r<0?!1:(e.splice(r,1),!0)}function se(e){let t=(e||"").toLowerCase().split(";")[0].trim();return t?!!(t.startsWith("image/")||t.startsWith("font/")||t.startsWith("video/")||t.startsWith("audio/")||t.startsWith("model/")||t==="text/css"||t==="application/javascript"||t==="text/javascript"||t==="application/wasm"||t==="application/font-woff"||t==="application/font-woff2"||t==="application/octet-stream"):!1}async function oe(e){let t=await fetch(e);if(!t.ok)throw new Error(`fetch ${e} -> ${t.status} ${t.statusText}`);return new Uint8Array(await t.arrayBuffer())}function Oe(e){return/\.bundle($|\?)/.test(e)||/\.js($|\?)/.test(e)?"application/javascript":/\.zip($|\?)/.test(e)?"application/zip":"application/javascript"}function Re(e){try{let t=new URL(e);return t.searchParams.get("lazy")==="true"?(t.searchParams.set("lazy","false"),t.toString()):e}catch{return e}}async function $e(e,t){let s=[];for(let o=0;o<t;o+=15e5){let a=Math.min(o+15e5,t),u=await w(e,`(window.__sootsimLastTransformedBundle?.text || "").slice(${o}, ${a})`);if(typeof u!="string")return null;s.push(u)}return s.join("")}async function Ge(e,t){(e.includes("--help")||e.includes("-h"))&&(xe(),process.exit(0));let r=[...e],s=await Ie(U(r,"--origin")),o=Se(s,U(r,"--public-origin")),a=U(r,"--events"),u=U(r,"--video"),y=U(r,"--video-duration-ms"),p=re(r,"--open"),P=re(r,"--assets-only"),B=q(r,{stripBooleanFlags:[],stripValueFlags:[]}),m=Y(B),l,C=[],g=[],z=null;try{if(l=await w(m,'(typeof window.__sootsimCaptureBundle === "function") ? window.__sootsimCaptureBundle() : null'),l?.bundleUrl){let n=new URL(l.bundleUrl).origin;C=(await w(m,`(window.__sootsimPreviewRecorder?.list?.(${JSON.stringify(n)}) || [])`)).filter(T=>{try{return!new URL(T.url).pathname.startsWith("/api/")}catch{return!0}});let i=await w(m,`(() => {
37
+ const rec = window.__sootsimPreviewRecorder
38
+ if (!rec?.list) return null
39
+ const all = rec.list()
40
+ const cross = all.filter((e) => {
41
+ try { return new URL(e.url).origin !== ${JSON.stringify(n)} } catch { return false }
42
+ })
43
+ return {
44
+ count: cross.length,
45
+ totalBytes: cross.reduce((n, e) => n + (e.size || 0), 0),
46
+ }
47
+ })()`);if(i&&i.count>0&&(console.log(` ${i.count} recorded cross-origin responses (${(i.totalBytes/1024).toFixed(1)} KiB)`),g=await w(m,`(() => {
48
+ const rec = window.__sootsimPreviewRecorder
49
+ if (!rec?.dump) return []
50
+ const bundleUrl = ${JSON.stringify(l.bundleUrl)}
51
+ return rec.dump().filter((r) => {
52
+ try {
53
+ const u = new URL(r.url)
54
+ if (u.origin !== ${JSON.stringify(n)}) return true
55
+ // bundle-origin api responses came from the rewritten
56
+ // /__app-api proxy at record time (re-keyed by the
57
+ // recorder's unwrap step). they need bodies attached the
58
+ // same way as cross-origin records \u2014 direct re-fetch from
59
+ // the dev server lacks the bundle's session cookies.
60
+ if (r.url !== bundleUrl && u.pathname.startsWith('/api/')) return true
61
+ return false
62
+ } catch { return false }
63
+ })
64
+ })()`),P)){let T=g.length;g=g.filter(I=>se(I.contentType));let F=i.totalBytes-g.reduce((I,$)=>I+($.size||0),0);console.log(` --assets-only: kept ${g.length}/${T} records (dropped ${(F/1024).toFixed(1)} KiB of API responses)`)}}l?.transformedBundle&&(z=await $e(m,l.transformedBundle.byteLength))}finally{m.close()}l||(console.error(" could not read bundle snapshot \u2014 is sootsim running and is the bundle loaded?"),process.exit(2)),l.bundleUrl||(console.error(` no ?bundle= URL on the current sootsim tab.
65
+ open the app you want to share first (e.g. sootsim open 8082), then run upload.`),process.exit(2));let c,A=!1;if(z!==null)c=new TextEncoder().encode(z),A=!0,console.log(` using post-transform bundle: ${(c.byteLength/1024).toFixed(1)} KiB`);else{let n=Re(l.bundleUrl);n!==l.bundleUrl&&console.log(" forcing lazy=false for self-contained bundle"),console.log(` capturing: ${n}`),c=await oe(n),console.log(` main bundle: ${(c.byteLength/1024).toFixed(1)} KiB`)}let S=C.filter(n=>n.url!==l.bundleUrl);P&&(S=S.filter(n=>se(n.contentType))),console.log(` fetching ${S.length} extra files\u2026`);let x=(await Promise.all(S.map(async n=>{try{let i=await oe(n.url);return{...n,bytes:i}}catch(i){return console.error(` warning: failed to re-fetch ${n.url}: ${i instanceof Error?i.message:i}`),null}}))).filter(n=>!!n),le=x.reduce((n,i)=>n+i.bytes.byteLength,0);console.log(` ${x.length} extra files: ${(le/1024).toFixed(1)} KiB`);let h;a&&(h=te(a));let f,O,N;if(u){if(f=te(u),O=u.endsWith(".mp4")?"video/mp4":u.endsWith(".gif")?"image/gif":"video/webm",y){let n=Number(y);(!Number.isFinite(n)||n<=0)&&(console.error(` invalid --video-duration-ms: ${y}`),await b(),process.exit(1)),N=Math.round(n)}console.log(` attaching flow video: ${(f.byteLength/1024).toFixed(1)} KiB (${O})`)}let d=Q(),ue=K();D({event:"preview_upload_started",identity:{userId:d?.kind==="session"?ue?.user?.id??null:null,repoId:d?.kind==="github"?d.repoId:null,installationId:d?.kind==="github"?d.installationId??null:null},properties:{origin:s,hasAuth:!!d,authMode:d?.kind??"none",bundleBytes:c.byteLength,isTransformed:A,extraFiles:x.length,recordedFetches:g.length,hasEvents:!!h,hasVideo:!!f}}),d||(console.error(" preview uploads need auth."),console.error(" set SOOTSIM_API_KEY=sk_sootsim_..., run `sootsim login`, or use the soot github runner."),await b(),process.exit(1));let de=X(d),ce=(()=>{try{return new URL(l.bundleUrl).origin}catch{return null}})(),W=(n,i,T,F,I,$,ye)=>{let V=Z($),me=V?ne(n):n;return{url:i,urlhash:T,method:F,bodyHash:I,contentType:$,responseHeaders:ye,bytes:me,encoding:V?"gzip":void 0}},E=[...x.map(n=>W(n.bytes,n.url,n.urlhash,"GET","-",n.contentType,n.responseHeaders)),...g.map(n=>W(Buffer.from(n.bodyBase64,"base64"),n.url,n.urlhash,n.method||"GET",n.bodyHash||"-",n.contentType,n.responseHeaders))],L=ne(c),pe=Te("sha256").update(c).digest("hex");console.log(` bundle raw=${(c.byteLength/1024).toFixed(1)} KiB gz=${(L.byteLength/1024).toFixed(1)} KiB`);let ge={contentHash:pe,bundleSizeBytes:c.byteLength,bundleContentType:Oe(l.bundleUrl),bundleEncoding:"gzip",bundleOrigin:ce,entry:l.entry,isTransformed:A,deviceSpec:l.deviceSpec,installationId:d.kind==="github"?d.installationId??void 0:void 0,repoId:d.kind==="github"?d.repoId:void 0,files:E.map(n=>({url:n.url,urlhash:n.urlhash,method:n.method,bodyHash:n.bodyHash,contentType:n.contentType,responseHeaders:n.responseHeaders,encoding:n.encoding,sizeBytes:n.bytes.byteLength})),events:h?{sizeBytes:h.byteLength}:void 0,flowVideo:f&&O?{sizeBytes:f.byteLength,contentType:O,durationMs:N}:void 0},j=new Map;for(let n of E)j.set(n.urlhash,n.bytes);let fe=Date.now(),R=L.byteLength;for(let n of E)R+=n.bytes.byteLength;h&&(R+=h.byteLength),f&&(R+=f.byteLength);let he=`${v(s)}/api/preview/upload/init`;console.log(` init: ${he}`);let k;try{let n=await ee({originBase:s,initBody:ge,bundleBytes:L,filesByHash:j,extras:{eventsBytes:h,videoBytes:f},authHeader:de,concurrency:16});k=n.finalize;let i=1+n.init.files.length+(n.init.events?1:0)+(n.init.flowVideo?1:0);console.log(` PUT ${i} objects in ${Date.now()-fe}ms (${(R/1024).toFixed(1)} KiB)`)}catch(n){let i=n;i.phase==="init"&&i.status===401&&(console.error(" preview upload requires a valid login."),console.error(" run `sootsim login` and retry."),i.message&&console.error(` ${i.message}`),await b(),process.exit(1)),console.error(` ${i.phase??"upload"} failed: ${i.message??String(n)}`),await b(),process.exit(1)}let G=`${o}${k.url}`;console.log(`
66
+ stored ${k.filesStored??0} extra files`),console.log(` preview: ${G}`),p&&await J(G),await b()}export{Ie as a,Se as b,Ge as c};
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.38 | (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(r){return new Promise(n=>{let e=c();e.question(r,t=>{e.close(),n(t.trim())})})}async function a(r,n=!0){let t=await s(` ${r} ${n?"[Y/n]":"[y/N]"} `);return t===""?n:t.toLowerCase().startsWith("y")}async function l(r,n){console.log(`
3
3
  ${r}
4
4
  `);for(let o=0;o<n.length;o++)console.log(` ${o+1}. ${n[o]}`);console.log();let e=await s(` choose [1-${n.length}]: `),t=parseInt(e,10);return t>=1&&t<=n.length?t-1:0}export{a,l as b};
@@ -0,0 +1,3 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{l as c}from"./chunk-6UJXRT7F.js";import{chmodSync as m,existsSync as g,mkdirSync as k,readFileSync as A,rmSync as i,writeFileSync as y}from"node:fs";import{dirname as l,join as D,resolve as p}from"node:path";var s=1,S="SOOTSIM_SHARED_AUTH_FILE",u="https://sootbean.com";function v(){let t=process.env[S];return t?.trim()?l(p(t)):c()}function a(){let t=process.env[S];return t?.trim()?p(t):D(v(),"desktop-auth.json")}function f(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}}function w(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:f(e.user),origin:r,source:n,updatedAt:o,validatedAt:h}}function O(){let t=a();if(!g(t))return null;try{let e=JSON.parse(A(t,"utf8")),r=w(e);return r||(i(t,{force:!0}),null)}catch{return i(t,{force:!0}),null}}function I(t){let e=a();k(l(e),{recursive:!0});let r={version:s,token:t.token.trim(),user:t.user?f(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
+ `);try{m(e,384)}catch{}return r}function d(){i(a(),{force:!0})}async function N(t){let e=O();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 d(),null;if(!n.ok)return e;let o=await n.json();return o.user?.id?I({token:e.token,user:o.user,origin:r,source:e.source,validatedAt:new Date().toISOString()}):(d(),null)}catch{return e}}export{O as a,I as b,d as c,N as d};
@@ -0,0 +1 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -0,0 +1,11 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as B,b as H,c as ne}from"./chunk-E473YTRQ.js";import{b as T}from"./chunk-SKNHJDYO.js";import{g as se}from"./chunk-JJVZMGRM.js";import{a as x,b as z}from"./chunk-QI4VLQ3A.js";import{c as re}from"./chunk-5XI3AB4I.js";import{a as Y}from"./chunk-FX3PPKSJ.js";import{d as te}from"./chunk-G23GIRBM.js";import{b as oe,c as S,d as w,e as $}from"./chunk-TR554AIH.js";import{c as N,d as g,e as F}from"./chunk-2ABGQIW7.js";import{E as Z,F as ee}from"./chunk-6UJXRT7F.js";import ve from"node:fs";import xe from"node:os";import j from"node:path";function ge(e){return e.replace(/^\[|\]$/g,"").toLowerCase()}function _(e){let o=ge(e);return o==="localhost"||o.endsWith(".localhost")||o==="0.0.0.0"||o==="::1"||/^127(?:\.\d{1,3}){3}$/.test(o)}function ie(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 we(e,o){return e?.includes("/one/metro-entry.bundle")?"one":typeof o=="string"&&o?"expo":"unknown"}function ce(e,o,t){return`${e}//${o}:${t}`}function be(e){if(typeof window>"u")return!1;try{let o=new URL(e);return _(o.hostname)&&_(window.location.hostname)&&o.origin!==window.location.origin}catch{return!1}}async function ae(e,o){let t={...o,cache:o?.cache??"no-store"};return be(e)?fetch(`/__fetch-proxy?url=${encodeURIComponent(e)}`,t):fetch(e,t)}function ye(e){return e==="https:"?443:80}function Se(e){let o=e.pathname||"/";return(o==="/"||o==="")&&!e.search&&!e.hash}async function le(e,o){let t=e.replace(/\/+$/,"");try{let n=await ae(`${t}/`,{headers:{"expo-platform":"ios"}});if(n.ok){let r=await n.json(),i=r?.extra?.expoClient||r?.extra||{},s=typeof r?.launchAsset?.url=="string"?r.launchAsset.url:void 0;if(s||i.name)return{bundleUrl:ne(s||`${t}${H}`),port:o,framework:we(s,i.sdkVersion),projectName:i.name}}}catch{}try{let n=await ae(`${t}/status`);if(n.ok&&(await n.text()).includes("packager-status:running"))return{bundleUrl:`${t}${H}`,port:o,framework:"metro"}}catch{}return null}async function $e(e){return le(ce("http:","localhost",e),e)}async function q(e){let o=e.trim();if(/^\d+$/.test(o)){let a=parseInt(o,10),l=await $e(a);if(l)return l;throw ie(`localhost:${a}`)}let t=o.startsWith("http")?o:`http://${o}`,n;try{n=new URL(t)}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:",i=n.port?parseInt(n.port,10):ye(r),s=ce(r,n.hostname,i);if(_(n.hostname)&&Se(n)){let a=await le(s,i);if(a)return a;throw ie(s)}return{bundleUrl:n.toString(),port:i,framework:"unknown"}}function qe(){console.error(" no sootsim desktop companion found."),console.error(""),console.error(" install the desktop app:"),console.error(" sootsim install-desktop"),console.error(""),console.error(" or wire sootsim into your own project so your dev server hosts the bridge:"),console.error(" sootsim setup-repo"),console.error("")}function me(e){let o=x();if(console.log(` note: no sootsim bridge detected on port ${e}`),o){console.log(" launch the installed companion with:"),console.log(" sootsim electron");return}console.log(""),console.log(" to get a bridge running, either:"),console.log(" sootsim install-desktop # download the electron app"),console.log(" sootsim setup-repo # wire sootsim into your own project")}function je(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")}var Ce={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 I(e){return new Promise(o=>setTimeout(o,e))}function G(e){return e.trim()}function W(e){try{let o=new URL(e),t=o.pathname.replace(/\/+$/,"")||"/";return o.searchParams.has("open")||o.searchParams.has("port")||o.searchParams.has("bundle")||o.searchParams.has("demo")||o.pathname.includes("/sootsim/index.html")||t==="/sootsim"||o.pathname==="/__soot"||o.pathname==="/__soot/"||t==="/rn"||/^\/rn\/[^/]+$/i.test(t)||/^\/app\/[^/]+$/i.test(t)||t==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(t)||/^\/__soot\/app\/[^/]+$/i.test(t)}catch{return!1}}async function at(e){let o=G(e);return(await q(o)).bundleUrl}function Q(e){let o=e.replace(/\/+$/,"")||"/";return o==="/__soot"||o.startsWith("/__soot/")?"/__soot":""}function Pe(e,o){let t=G(e),n=new URL(o),r=Q(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(t)?n.pathname=`${r}/rn/${t}`:(n.pathname=`${r}/rn`,n.searchParams.set("open",t)),n.toString()}function Ie(e){let o=G(e);return/^\d+$/.test(o)||/^https?:\/\//i.test(o)?!0:/^(localhost|127\.0\.0\.1|\[::1\]|[^/]+\.localhost):\d+(?:\/.*)?$/i.test(o)}async function Ue(e,o){let t=await q(e),n=new URL(o),r=Q(n.pathname);return n.pathname=`${r}/rn`,n.searchParams.delete("open"),n.searchParams.delete("port"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.set("bundle",t.bundleUrl),n.toString()}function ke(e){return e.startsWith("~/")?j.join(xe.homedir(),e.slice(2)):j.isAbsolute(e)?e:j.resolve(process.cwd(),e)}function Me(e){let o={};for(let t=0;t<e.length;t++){if(e[t]!=="--replace")continue;let n=e[t+1];n||(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let r=n.indexOf("=");(r<=0||r===n.length-1)&&(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let i=n.slice(0,r).trim(),s=ke(n.slice(r+1).trim());ve.existsSync(s)||(console.error(` sootsim open: replacement file not found: ${s}`),process.exit(1)),o[i]={file:s},t++}return Object.keys(o).length>0?{modules:o}:void 0}function ue(){let e=Z();return ee(e)&&e.runtimePort>0?`http://localhost:${e.runtimePort}/`:Y}async function R(e,o=ue()){if(!e)return new URL(o).toString();if(W(e))return new URL(e).toString();let t=Ce[e.toLowerCase()];if(t){let n=new URL(o),r=Q(n.pathname);return n.pathname=`${r}${t}`,n.toString()}return Ie(e)?Ue(e,o):Pe(e,o)}function de(e,o){let t=e?.url||e?.origin||o;try{let n=new URL(t);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.toString()}catch{return o}}async function Te(e,o,t){let n=new URL(await R(e,o));return n.searchParams.set("inspectOpen",t),n.toString()}async function Be(e,o,t,n={}){let r=n.attempts??30,i=n.intervalMs??500,s=n.minNodeCount??10;for(let a=0;a<r;a++){let l=w(e,{commandTimeoutMs:o,simId:t,simIdSource:"flag"});try{let m=await l.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount()) || 0)()"});if(typeof m=="number"&&m>s)return{bridge:l,count:m}}catch{}l.close(),await I(i)}return null}function _e(e){if(!e)return null;try{let o=new URL(e);if(o.searchParams.has("bundle")){let t=o.searchParams.get("bundle")||"";try{let n=new URL(t),r=n.pathname.length>36?`...${n.pathname.slice(-36)}`:n.pathname;return`bundle ${n.host}${r}`}catch{return"bundle"}}return o.searchParams.has("port")?`connect :${o.searchParams.get("port")||""}`:o.searchParams.has("open")?`connect ${o.searchParams.get("open")||""}`:o.searchParams.has("demo")?`demo ${o.searchParams.get("demo")||"default"}`:o.pathname.includes("/sootsim/index.html")||o.pathname==="/sootsim/"||o.pathname==="/sootsim"?"embedded sootsim":null}catch{return null}}function Oe(e,o){if(e.length===0){console.log(" no sims connected");return}console.log(` connected sims (${e.length}):
3
+ `);for(let t of e){let n=t.lockedBy&&t.lockExpiresAt?`locked by ${t.lockedBy} (${Math.max(0,Math.round((t.lockExpiresAt-Date.now())/1e3))}s)`:"",r=[t.isPrimary?"primary":"",t.id===o?"selected":"",t.readyState,t.attachedCliCount&&t.attachedCliCount>0?"in use":"",t.userFocused?"focused":"",n].filter(Boolean);console.log(` ${t.id}${r.length?` [${r.join(", ")}]`:""}`);let i=_e(t.url);if(i&&console.log(` loaded: ${i}`),t.url?console.log(` url: ${t.url}`):t.origin&&console.log(` origin: ${t.origin}`),t.title&&console.log(` title: ${t.title}`),console.log(` connected: ${new Date(t.connectedAt).toISOString()}`),t.lastActiveAt&&t.lastActiveAt>0){let s=Math.round((Date.now()-t.lastActiveAt)/1e3),a=s<60?`${s}s ago`:s<3600?`${Math.round(s/60)}m ago`:`${Math.round(s/3600)}h ago`;console.log(` last active: ${a}`)}}}async function O(e,o,t,n={}){let r=n.attempts??30,i=n.intervalMs??500;for(let s=0;s<r;s++){let a=w(e,{commandTimeoutMs:o});try{let m=(await a.listSims()).find(t);if(m)return m}catch{}finally{a.close()}await I(i)}return null}async function Re(e,o,t,n={}){let r=n.attempts??20,i=n.intervalMs??250;for(let s=0;s<r;s++){let a=w(e,{commandTimeoutMs:o});try{let m=(await a.listSims()).find(b=>b.id===t);if(!m||m.readyState!=="open")return!0}catch{return!0}finally{a.close()}await I(i)}return!1}function L(e,o){if(o){let r=o.trim(),i=e.find(s=>s.id===r);if(!i)throw new Error(`no sim connected with id ${r}`);return i}let t=e.find(r=>r.isPrimary&&r.readyState==="open");if(t)return t;let n=e.find(r=>r.readyState==="open");if(n)return n;throw new Error("no sim connected")}function C(e,o,t){console.log(` ${t==="current sim"?"loaded":"opened"}: ${e} [${t}]`),console.log(` current sim: ${o.id}`),console.log(JSON.stringify({simId:o.id,url:o.url},null,2))}async function P(e,o,t){if(t.includes("--no-describe"))return;let n=process.env.SOOTSIM_QUIET_TARGET_NOTICE;process.env.SOOTSIM_QUIET_TARGET_NOTICE="1";try{await Le(e,o,{stableMs:150,maxMs:400});let r=w(e,{commandTimeoutMs:3e3,simId:o,cliLabel:"open --describe",simIdSource:"flag"});try{let s=`(async () => {
4
+ const t = window.__sootsimTest
5
+ const ms = window.SootSim?.bridges?.mainShell
6
+ if (!t) return null
7
+ let shell = null
8
+ try { shell = ms?.getState ? await ms.getState() : null } catch {}
9
+ const tree = await t.dumpTree(12, ${JSON.stringify({describe:!0,verbose:!1,filter:""})})
10
+ return { tree, shell }
11
+ })()`,a=await r.send({type:"evaluate",code:s});if(!a?.tree)return;if(console.log(""),a.shell?.state){let l=[`state=${a.shell.state}`,a.shell.activeApp?`app=${a.shell.activeApp}`:null].filter(Boolean);console.log(` shell: ${l.join(" ")}`)}console.log(a.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 Le(e,o,t){let n=Date.now()+t.maxMs,r="(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()",i=w(e,{commandTimeoutMs:2e3,simId:o,simIdSource:"flag"});try{let s=-1,a=0;for(;Date.now()<n;){let l=-1;try{let m=await i.send({type:"evaluate",code:r});typeof m=="number"&&(l=m)}catch{}if(l>=0&&l===s){if(Date.now()-a>=t.stableMs)return}else s=l,a=Date.now();await I(50)}}finally{i.close()}}async function ct(e,o={}){let t=S(e,{port:o.port,commandTimeoutMs:o.timeoutMs}),n=$(t);try{let r=await n.listSims();Oe(r,t.simId)}finally{n.close()}}async function lt(e,o={}){let t=S(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--new","--headless","--ephemeral"],stripValueFlags:["--base-url","--replace","--driver","--profile"]}),n=e.find((c,d)=>e[d-1]==="--profile"),r=e.includes("--ephemeral");n&&r&&(console.error(" sootsim open: --profile cannot be combined with --ephemeral"),process.exit(1));let i=n?re(n).id:void 0,s=!!i||r,a=e.includes("--new")||s,l=Me(e);a&&t.simIdSource==="flag"&&(console.error(" sootsim open: --new, --profile, and --ephemeral cannot be combined with --sim"),process.exit(1));let m=t.positional[0]||"",b=e.find((c,d)=>e[d-1]==="--driver")||"",fe=e.includes("--headless"),v=e.find((c,d)=>e[d-1]==="--base-url")||ue(),J=e.includes("--base-url"),K=N();if(!a&&(t.simIdSource==="flag"||t.simIdSource==="saved"&&!!K)){let c=$(t),d=t.simId?` --sim ${t.simId}`:"",u=!1;try{let p=null;try{let h=await c.listSims();if(t.simIdSource==="saved"?(p=h.find(y=>y.id===K&&y.readyState==="open")??null,p||F()):p=L(h,t.simId),!p)if(t.simIdSource==="saved")u=!0;else throw new Error("no sim connected");if(!u&&p){let y=J||W(m)?v:de(p,v),M=await R(m,B(y,l));c.send({type:"evaluate",simId:p.id,code:`window.location.href = ${JSON.stringify(M)}`}).catch(()=>{})}}catch(h){console.error(` open failed: ${h instanceof Error?h.message:String(h)}`),await T(c,{errorsCommand:`sootsim get errors 5${d}`,warningsCommand:`sootsim get warnings 5${d}`,requestsCommand:`sootsim get requests 5${d}`}),process.exit(1)}if(!u&&p){await I(1500);let h=await Be(t.wsPort,t.commandTimeoutMs,p.id);h||(console.error(" timed out waiting for current sim to load target"),process.exit(1)),h.bridge.close(),g(p.id);let y=J||W(m)?v:de(p,v),M=await R(m,B(y,l));C(M,{...p,url:M},"current sim"),await P(t.wsPort,p.id,e);return}}finally{c.close()}}let V=B(v,l),he=await R(m,V),X=`cli-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,f=await Te(m,V,X),E={newWindow:!0},U=c=>c.url?.includes(`inspectOpen=${X}`)??!1;if(b){let c=se(b);c||(console.error(` unknown driver "${b}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let d=await c.launch({url:f,headless:fe,newWindow:E.newWindow,profileId:i,ephemeralProfile:r});d.launched||(console.error(` ${c.name} driver: ${d.message}`),process.exit(1));let u=await O(t.wsPort,t.commandTimeoutMs,U,{attempts:60,intervalMs:500});u||(console.error(" timed out waiting for opened sim to connect"),process.exit(1)),g(u.id),C(f,u,`${c.name} driver`),await P(t.wsPort,u.id,e);return}if(s){let c=x();c||(console.error(" profiles require electron or playwright; install the desktop companion or use `--driver playwright`"),process.exit(1));try{(await z(f,c,{profileId:i,ephemeralProfile:r})).launched||(console.error(" desktop companion failed to start"),process.exit(1))}catch(u){console.error(` desktop companion failed: ${u instanceof Error?u.message:String(u)}`),process.exit(1)}let d=await O(t.wsPort,t.commandTimeoutMs,U,{attempts:40,intervalMs:500});d||(console.error(" timed out waiting for profiled sim to connect"),process.exit(1)),g(d.id),C(f,d,"desktop companion"),await P(t.wsPort,d.id,e);return}let D=!1,A=!1;try{let c=w(t.wsPort,{commandTimeoutMs:2e3});try{await c.listSims(),D=!0}finally{c.close()}}catch{}if(D)try{let c=w(t.wsPort,{commandTimeoutMs:3e3});try{await c.openUrl(f,E),A=!0}finally{c.close()}}catch{}if(!A){let c=x();if(c)try{if((await z(f,c)).launched){let u=await O(t.wsPort,t.commandTimeoutMs,U,{attempts:20,intervalMs:500});if(u){g(u.id),C(f,u,"desktop companion"),await P(t.wsPort,u.id,e);return}}}catch{}if(await te(f,E),!D){console.log(` opened: ${he}`),me(t.wsPort);return}}let k=await O(t.wsPort,t.commandTimeoutMs,U,{attempts:30,intervalMs:500});k||(console.error(" timed out waiting for opened sim to connect"),process.exit(1)),g(k.id),C(f,k,A?"bridge":"direct shell open"),await P(t.wsPort,k.id,e)}async function pe(e,o={}){let t=S(e,{port:o.port,commandTimeoutMs:o.timeoutMs}),n=$(t),r=t.simId?` --sim ${t.simId}`:"";try{try{let i=await n.listSims(),s=L(i,t.positional[0]||t.simId);await n.focusSim(s.id),g(s.id),console.log(` using: ${s.id}`)}catch(i){console.error(` use failed: ${i instanceof Error?i.message:String(i)}`),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()}}async function mt(e,o={}){await pe(e,o)}async function dt(e,o={}){await pe(e,o)}async function ut(e,o={}){let t=S(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=$(t);try{try{let i=await r.listSims(),s=L(i,t.positional[0]||t.simId),a=n&&s.lockedBy&&s.lockedByKind!=="user-active"?s.lockedBy:null,l=await r.claim(s.id,{force:n});g(s.id);let m=Math.max(0,Math.round((l.lockExpiresAt-Date.now())/1e3)),b=l.bootedCount>0?` (booted ${l.bootedCount})`:"";console.log(` claimed: ${l.simId} [${m}s]${b}`),a&&console.log(` took over from: ${a}`)}catch(i){if(i instanceof oe){let s=Math.max(0,Math.round(i.lock.expiresInMs/1e3));console.error(` claim failed: locked by ${i.lock.by} for ${s}s more`),console.error(" use --force to take it, or `sootsim open --new` for a fresh sim"),process.exit(1)}console.error(` claim failed: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}finally{r.close()}}async function pt(e,o={}){let t=S(e,{port:o.port,commandTimeoutMs:o.timeoutMs}),n=$(t),r=t.simId?` --sim ${t.simId}`:"";try{try{let i=await n.listSims(),s=L(i,t.positional[0]||t.simId),a=i.find(m=>m.id!==s.id&&m.readyState==="open");if(await n.closeSim(s.id),!await Re(t.wsPort,t.commandTimeoutMs,s.id)){console.log(` close requested: ${s.id} (still connected)`);return}N()===s.id&&(a?g(a.id):F()),console.log(` closed: ${s.id}`)}catch(i){console.error(` close failed: ${i instanceof Error?i.message:String(i)}`),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{qe as a,je as b,at as c,ue as d,R as e,Te as f,_e as g,Oe as h,O as i,ct as j,lt as k,mt as l,dt as m,ut as n,pt as o};
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.38 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ var i="sootsimConfig";function e(n){return!!n&&Object.keys(n).length>0}function s(n){return n?e(n.modules)||e(n.turboModules)||e(n.nativeModules)||e(n.env)||e(n.settings)||e(n.initialState):!1}function u(n,o){let t=new URL(n);return s(o)?t.searchParams.set(i,JSON.stringify(o)):t.searchParams.delete(i),t.toString()}var g="/index.bundle?platform=ios&dev=true&hot=true&minify=false";function r(n){return/^https?:\/\//i.test(n)}function a(n){return n.endsWith(".bundle")}function l(n){try{let o=r(n),t=new URL(n,"http://soot.local");return t.pathname=t.pathname.replace(/\.\.bundle$/,".bundle"),a(t.pathname)?(t.searchParams.delete("transform.bytecode"),o?t.toString():`${t.pathname}${t.search}${t.hash}`):n}catch{return n}}export{u as a,g as b,l as c};