sootsim 0.1.40 → 0.1.42
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.
- package/README.md +15 -15
- package/dist-cli/bin.js +4 -4
- package/dist-cli/chunks/{agent-3F5PO4NL.js → agent-4BBZUWD2.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-LVUUZRWL.js → agent-wrapper-TA5GG3MV.js} +2 -2
- package/dist-cli/chunks/{assert-4WMVS3WU.js → assert-7GHUOGLI.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-7BJDOYUU.js +2 -0
- package/dist-cli/chunks/beta-2LIEPFEJ.js +2 -0
- package/dist-cli/chunks/{chunk-QUULF2II.js → chunk-2GKZS2ZZ.js} +2 -2
- package/dist-cli/chunks/chunk-2XCCV7J3.js +2 -0
- package/dist-cli/chunks/{chunk-CCZHRBXJ.js → chunk-3PN6HIAM.js} +1 -1
- package/dist-cli/chunks/{chunk-W2XRHDQQ.js → chunk-4574AJAK.js} +2 -2
- package/dist-cli/chunks/chunk-543BSGQG.js +4 -0
- package/dist-cli/chunks/{chunk-FNIL6BYS.js → chunk-5EBERDK7.js} +1 -1
- package/dist-cli/chunks/{chunk-KGVH3YAG.js → chunk-5PZPKGUJ.js} +2 -2
- package/dist-cli/chunks/{chunk-QMBYRPRK.js → chunk-5TRJK5SO.js} +1 -1
- package/dist-cli/chunks/chunk-64AKKWVB.js +1 -0
- package/dist-cli/chunks/{chunk-YKEBL6GE.js → chunk-6MYXKMLG.js} +1 -1
- package/dist-cli/chunks/{chunk-WZE6T3GT.js → chunk-6R3CVNXC.js} +1 -1
- package/dist-cli/chunks/chunk-76WF7UIG.js +17 -0
- package/dist-cli/chunks/chunk-A2R42ONP.js +27 -0
- package/dist-cli/chunks/{chunk-LXR5EI74.js → chunk-BBRAYGDX.js} +2 -2
- package/dist-cli/chunks/{chunk-MLCBIX7O.js → chunk-BVCZIJ2X.js} +2 -2
- package/dist-cli/chunks/chunk-BZFKV7CT.js +56 -0
- package/dist-cli/chunks/{chunk-YJMXGTP4.js → chunk-CZZDYQBA.js} +1 -1
- package/dist-cli/chunks/{chunk-Y66CDFAT.js → chunk-D5TKAFJ3.js} +1 -1
- package/dist-cli/chunks/{chunk-OV5TY7M3.js → chunk-DNSKIJSB.js} +2 -2
- package/dist-cli/chunks/{chunk-EOWN4ZFJ.js → chunk-DUVJOJTP.js} +2 -2
- package/dist-cli/chunks/{chunk-6XI4VHIL.js → chunk-DXQKMDX2.js} +2 -2
- package/dist-cli/chunks/{chunk-Z3I2I4IO.js → chunk-EDXBJUHH.js} +3 -3
- package/dist-cli/chunks/chunk-EZGUKWD5.js +1 -0
- package/dist-cli/chunks/{chunk-DSTHAISO.js → chunk-FDB3P2GV.js} +1 -1
- package/dist-cli/chunks/{chunk-LCES5ZJI.js → chunk-I4LBW6ED.js} +2 -2
- package/dist-cli/chunks/chunk-IFY75LQ3.js +1 -0
- package/dist-cli/chunks/{chunk-553OZX4H.js → chunk-ITQGNQE3.js} +2 -2
- package/dist-cli/chunks/{chunk-5GK4YX7O.js → chunk-J6HT2ZJW.js} +1 -1
- package/dist-cli/chunks/{chunk-TK2IPNHL.js → chunk-KQN7OUQ6.js} +2 -2
- package/dist-cli/chunks/{chunk-Y5CFIRLN.js → chunk-L53QRCQZ.js} +1 -1
- package/dist-cli/chunks/{chunk-KVOMVYG6.js → chunk-LAOTVMTO.js} +2 -2
- package/dist-cli/chunks/chunk-LJLRHMLK.js +1 -0
- package/dist-cli/chunks/{chunk-WQXG4I5N.js → chunk-LXZK2TIS.js} +2 -2
- package/dist-cli/chunks/{chunk-6X5NQJT7.js → chunk-MQOJIYEY.js} +20 -20
- package/dist-cli/chunks/chunk-NLYIKZIF.js +62 -0
- package/dist-cli/chunks/{chunk-WPS3TIOB.js → chunk-Q26NNL4G.js} +1 -1
- package/dist-cli/chunks/chunk-QLGR4M5H.js +11 -0
- package/dist-cli/chunks/{chunk-U3JD6X75.js → chunk-QWGMNIWG.js} +2 -2
- package/dist-cli/chunks/chunk-R3KU3IBN.js +117 -0
- package/dist-cli/chunks/{chunk-5IAIIX7B.js → chunk-SGBD3EAX.js} +3 -3
- package/dist-cli/chunks/{chunk-DEBXVPIE.js → chunk-UY6HKNEV.js} +1 -1
- package/dist-cli/chunks/{chunk-4L45Q3YX.js → chunk-WSISSPE3.js} +2 -2
- package/dist-cli/chunks/{chunk-PKB6IEGM.js → chunk-WW4G4D4A.js} +2 -2
- package/dist-cli/chunks/{chunk-BZED27B2.js → chunk-Y4ENWAOJ.js} +2 -2
- package/dist-cli/chunks/{compat-NBFWHK5S.js → compat-GWIATWPP.js} +5 -5
- package/dist-cli/chunks/{config-JEDQ3NHA.js → config-OXHJXY6N.js} +2 -2
- package/dist-cli/chunks/control-HJ2RPHYO.js +2 -0
- package/dist-cli/chunks/cpu-profile-MBYPGUJH.js +2 -0
- package/dist-cli/chunks/{daemon-HOL7J3BI.js → daemon-3N3QWMFU.js} +2 -2
- package/dist-cli/chunks/{debug-LNVMIWD6.js → debug-POCRM56I.js} +3 -3
- package/dist-cli/chunks/demo-app-registry-XABEINTD.js +2 -0
- package/dist-cli/chunks/{detox-EEZPH3DZ.js → detox-4NXKQ2CS.js} +2 -2
- package/dist-cli/chunks/{device-GVLYQI7X.js → device-DURJHKK5.js} +2 -2
- package/dist-cli/chunks/diagnose-IMXDGRVA.js +41 -0
- package/dist-cli/chunks/drivers-VXSNI7K2.js +2 -0
- package/dist-cli/chunks/{electron-UDV6K3IH.js → electron-NGWA52N6.js} +3 -3
- package/dist-cli/chunks/flow-TCG5XPDK.js +2 -0
- package/dist-cli/chunks/{hints-46PJLATZ.js → hints-5UNZ7BR2.js} +2 -2
- package/dist-cli/chunks/{home-paths-XD7AOYU7.js → home-paths-TENEFM4L.js} +2 -2
- package/dist-cli/chunks/{inspect-EDIKZ6O2.js → inspect-IWMH6MUT.js} +94 -92
- package/dist-cli/chunks/install-IKBAY4PQ.js +2 -0
- package/dist-cli/chunks/{install-desktop-CX6ATQTR.js → install-desktop-ABAWCLFJ.js} +3 -3
- package/dist-cli/chunks/{keys-CXQIYEVW.js → keys-NET26VLH.js} +2 -2
- package/dist-cli/chunks/{launch-DCFRKVD3.js → launch-TKIA4RC4.js} +3 -3
- package/dist-cli/chunks/{login-HCIZL5GT.js → login-AWT3GU5M.js} +4 -4
- package/dist-cli/chunks/{logout-7X2YHJY3.js → logout-R2RUNXHO.js} +2 -2
- package/dist-cli/chunks/{maestro-TY622MIW.js → maestro-552237HC.js} +2 -2
- package/dist-cli/chunks/{preview-DYI6ESOK.js → preview-GKIGPZUO.js} +2 -2
- package/dist-cli/chunks/{profile-7SXJEJTG.js → profile-U64JPCPD.js} +2 -2
- package/dist-cli/chunks/{react-VGSDY766.js → react-FWSV5JH2.js} +2 -2
- package/dist-cli/chunks/record-FLWDPJIP.js +7 -0
- package/dist-cli/chunks/runtime-AGNC2TK6.js +2 -0
- package/dist-cli/chunks/{runtime-delivery-PWLODFCY.js → runtime-delivery-22PV7UED.js} +2 -2
- package/dist-cli/chunks/{screenshot-PTKY4UU4.js → screenshot-4P3TL7CN.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-HSV7VY4G.js → screenshot-mode-GX3Q3IZ6.js} +2 -2
- package/dist-cli/chunks/{screenshots-VY7VAGSV.js → screenshots-5HSLPDWZ.js} +2 -2
- package/dist-cli/chunks/server-Q3ZD4BEF.js +35 -0
- package/dist-cli/chunks/setup-repo-NQVN5PK7.js +2 -0
- package/dist-cli/chunks/{skills-KEPQLCMR.js → skills-M2CWX5ZC.js} +2 -2
- package/dist-cli/chunks/{start-5CJTBNRM.js → start-24EAF2KS.js} +4 -4
- package/dist-cli/chunks/store-GI3SJOKH.js +2 -0
- package/dist-cli/chunks/telemetry-73Z4FAUH.js +2 -0
- package/dist-cli/chunks/{test-REKHGKFE.js → test-AJBULIVR.js} +3 -3
- package/dist-cli/chunks/{three-mode-FZYHB4ZQ.js → three-mode-JBZSQQIQ.js} +2 -2
- package/dist-cli/chunks/{timeline-CWZAY52K.js → timeline-VVGWQSVU.js} +2 -2
- package/dist-cli/chunks/{upgrade-AIUJEF5F.js → upgrade-IOGHQT7J.js} +2 -2
- package/dist-cli/chunks/upload-Z4PPGOX6.js +2 -0
- package/dist-cli/chunks/web-XIMVN6KZ.js +2 -0
- package/dist-cli/chunks/{what-happened-JSQQVQGE.js → what-happened-STVD3KZ2.js} +2 -2
- package/dist-cli/chunks/whoami-L62IGS4U.js +2 -0
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +14 -8
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/vite-base.cjs +14 -8
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/dist-cli/chunks/auto-bootstrap-Q4A3PTF5.js +0 -2
- package/dist-cli/chunks/beta-CLLKUB5X.js +0 -2
- package/dist-cli/chunks/chunk-4IAKB3C4.js +0 -117
- package/dist-cli/chunks/chunk-CAJ247SC.js +0 -2
- package/dist-cli/chunks/chunk-D2ZMP7G4.js +0 -61
- package/dist-cli/chunks/chunk-D4Z7MWQY.js +0 -11
- package/dist-cli/chunks/chunk-DHJIXXWG.js +0 -27
- package/dist-cli/chunks/chunk-DPZDTJVQ.js +0 -1
- package/dist-cli/chunks/chunk-FFR7EA4U.js +0 -1
- package/dist-cli/chunks/chunk-I7KXFJDK.js +0 -1
- package/dist-cli/chunks/chunk-J6BPROH4.js +0 -4
- package/dist-cli/chunks/chunk-PNGBWMQH.js +0 -17
- package/dist-cli/chunks/chunk-S4PJMUC7.js +0 -2
- package/dist-cli/chunks/chunk-XWXFUFB2.js +0 -1
- package/dist-cli/chunks/control-IMWZVYC3.js +0 -2
- package/dist-cli/chunks/cpu-profile-MQPUSRHG.js +0 -22
- package/dist-cli/chunks/demo-app-registry-4RFMJ4FM.js +0 -2
- package/dist-cli/chunks/diagnose-JQ7DPTSL.js +0 -41
- package/dist-cli/chunks/drivers-JUW6JBWH.js +0 -2
- package/dist-cli/chunks/flow-JOW23WNH.js +0 -2
- package/dist-cli/chunks/install-CCC3IF5S.js +0 -2
- package/dist-cli/chunks/record-7JX2SMVP.js +0 -37
- package/dist-cli/chunks/runtime-FTOQD7QK.js +0 -2
- package/dist-cli/chunks/server-EDB3EK4K.js +0 -35
- package/dist-cli/chunks/setup-repo-S2GFZR7F.js +0 -2
- package/dist-cli/chunks/store-SCRULNVS.js +0 -2
- package/dist-cli/chunks/telemetry-RC3OT67I.js +0 -2
- package/dist-cli/chunks/upload-UDA5ITTE.js +0 -2
- package/dist-cli/chunks/whoami-5WUUPIRN.js +0 -2
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# SootSim
|
|
2
2
|
|
|
3
|
-
CLI + framework plugins for
|
|
3
|
+
CLI + framework plugins for SootBean's browser-native simulator.
|
|
4
4
|
|
|
5
|
-
this package is the public, publishable face of
|
|
5
|
+
this package is the public, publishable face of SootSim. it contains:
|
|
6
6
|
|
|
7
|
-
- `sootsim` CLI (bridge client — drives a running
|
|
7
|
+
- `sootsim` CLI (bridge client — drives a running SootSim instance over
|
|
8
8
|
WebSocket for describing UI, tapping elements, recording flows, etc.)
|
|
9
|
-
- `sootsim/vite` — vite plugin for wrapping an app bundler with
|
|
9
|
+
- `sootsim/vite` — vite plugin for wrapping an app bundler with SootSim
|
|
10
10
|
- `sootsim/metro` — metro plugin for wrapping a react native bundler
|
|
11
|
-
- `sootsim/skills` — registry for
|
|
11
|
+
- `sootsim/skills` — registry for SootBean-flavored automation skills
|
|
12
12
|
|
|
13
13
|
the rendering engine itself (canvas renderer, yoga layout, iOS/Android shell
|
|
14
14
|
chrome, wasm, electron shell) lives in the private `sootsim-engine` workspace
|
|
@@ -18,12 +18,12 @@ Platform status: iOS is the parity baseline. Android is bootstrapped and
|
|
|
18
18
|
usable for focused conformance slices, with Android bundle/runtime identity,
|
|
19
19
|
device profiles, initial shell chrome, gesture and three-button nav proof,
|
|
20
20
|
Android system UI/window metrics with cutout-safe insets, and Android
|
|
21
|
-
|
|
21
|
+
SootSim-only matrix runs.
|
|
22
22
|
Android `react-native-screens`, `react-native-safe-area-context`,
|
|
23
23
|
RefreshControl, keyboard/IME resize, EdgeEffect, scroll deceleration/fading
|
|
24
24
|
edges/scrollbars, and basic system-bar API support are improving but still need
|
|
25
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
|
|
26
|
+
It is not full Android parity until the Android launch gates in the SootBean repo
|
|
27
27
|
plan pass.
|
|
28
28
|
|
|
29
29
|
## getting started
|
|
@@ -43,7 +43,7 @@ using the same device list as `Window >`.
|
|
|
43
43
|
|
|
44
44
|
## CLI
|
|
45
45
|
|
|
46
|
-
the CLI is the primary debugging surface for
|
|
46
|
+
the CLI is the primary debugging surface for SootSim. use it first for runtime
|
|
47
47
|
inspection, interaction, animation debugging, shell tracing, screenshots, and
|
|
48
48
|
flow capture instead of treating it as a test-only tool.
|
|
49
49
|
|
|
@@ -66,12 +66,12 @@ bun sootsim test --detox # shared Detox-style parity suite against sootsim
|
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
see the full command reference via `bun sootsim --help` or at
|
|
69
|
-
`src/features/site/docs/sootsim/cli/` in the
|
|
69
|
+
`src/features/site/docs/sootsim/cli/` in the SootBean repo.
|
|
70
70
|
|
|
71
71
|
## coming from detox
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
(`import { by, element, expect, device } from 'detox'`) run against
|
|
73
|
+
SootSim ships a drop-in detox driver. your existing detox test files
|
|
74
|
+
(`import { by, element, expect, device } from 'detox'`) run against SootSim
|
|
75
75
|
with no code changes — just add one line to your jest config:
|
|
76
76
|
|
|
77
77
|
```js
|
|
@@ -90,7 +90,7 @@ see `docs/migrating-from-detox.md` for details.
|
|
|
90
90
|
|
|
91
91
|
## coming from maestro
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
SootSim's flow runner natively speaks maestro's YAML format. point it at your
|
|
94
94
|
existing `.maestro/` directory:
|
|
95
95
|
|
|
96
96
|
```sh
|
|
@@ -118,7 +118,7 @@ bun sootsim screenshot --with-frame --output /tmp/sootsim-framed.png
|
|
|
118
118
|
bun sootsim record --duration 5 --output /tmp/sootsim-anim.mp4
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
-
`sootsim screenshot --with-frame` composes the real
|
|
121
|
+
`sootsim screenshot --with-frame` composes the real SootSim shell device chrome
|
|
122
122
|
around the raw screen bitmap. it reuses the shell bezel/button geometry and
|
|
123
123
|
still excludes the electron top bar, rail gutter, and other window chrome.
|
|
124
124
|
|
|
@@ -214,7 +214,7 @@ module.exports = withSootsim({ /* your metro config */ })
|
|
|
214
214
|
|
|
215
215
|
## development
|
|
216
216
|
|
|
217
|
-
this package is part of the
|
|
217
|
+
this package is part of the SootBean monorepo. to build the CLI bundle:
|
|
218
218
|
|
|
219
219
|
```sh
|
|
220
220
|
bun run build:cli
|
package/dist-cli/bin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/*! sootsim v0.1.
|
|
3
|
-
import{a as E}from"./chunks/chunk-
|
|
2
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
3
|
+
import{a as E}from"./chunks/chunk-CZZDYQBA.js";import{a as l}from"./chunks/chunk-LXZK2TIS.js";import{a as A,b as k,c as S,d as C,e as u,f as T}from"./chunks/chunk-R3KU3IBN.js";import{a as p}from"./chunks/chunk-2XCCV7J3.js";import{a as v,d as _}from"./chunks/chunk-J6HT2ZJW.js";import"./chunks/chunk-L53QRCQZ.js";import"./chunks/chunk-EZGUKWD5.js";import{z as L}from"./chunks/chunk-6MYXKMLG.js";import"./chunks/chunk-UY6HKNEV.js";function R(){let t=L();return`sootsim CLI v${E()} \xB7 runtime ${t?`v${t}`:"not installed"}`}function g(){let t=k({bridgePort:7668,defaultShellUrl:p},l()),e=`
|
|
4
4
|
${_}
|
|
5
5
|
`;console.log(`${R()}
|
|
6
6
|
${e}${t}
|
|
@@ -21,11 +21,11 @@ clear the shared desktop session used by the CLI and electron.
|
|
|
21
21
|
|
|
22
22
|
show the current shared desktop account used by the CLI and electron.
|
|
23
23
|
`);return}let e=S(t,{bridgePort:7668,defaultShellUrl:p});if(!e){console.log(`unknown command: ${t}`);return}console.log(`${e}
|
|
24
|
-
`)}function x(t){let e=t instanceof Error?t.message:String(t);(/^command timed out after \d+s$/.test(e)||e.startsWith("sim disconnected:")||e.startsWith("bridge never reconnected")||e.startsWith("no sim connected with id ")||e.startsWith("sootsim bridge daemon is not running")||e.startsWith("refusing to install the persistent sootsim daemon"))&&!process.env.SOOTSIM_VERBOSE&&(process.stderr.write(` ${e}
|
|
24
|
+
`)}function x(t){let e=t instanceof Error?t.message:String(t);(/^command timed out after \d+s$/.test(e)||e.startsWith("sim disconnected:")||e.startsWith("bridge never reconnected")||e.startsWith("no sim connected with id ")||e.startsWith("could not connect to ws://")||e.startsWith("sootsim bridge daemon is not running")||e.startsWith("refusing to install the persistent sootsim daemon"))&&!process.env.SOOTSIM_VERBOSE&&(process.stderr.write(` ${e}
|
|
25
25
|
`),process.exit(1)),t instanceof Error&&t.stack?process.stderr.write(`${t.stack}
|
|
26
26
|
`):process.stderr.write(`${e}
|
|
27
27
|
`),process.exit(1)}process.on("unhandledRejection",x);process.on("uncaughtException",x);var M=typeof __SOOTSIM_STANDALONE__<"u"&&__SOOTSIM_STANDALONE__,P=new Set(["preview","electron","install-desktop"]);function F(t){!M||!P.has(t)||(process.stderr.write(` sootsim ${t} isn't available in the standalone binary \u2014
|
|
28
28
|
it needs vite / electron / playwright from a project's node_modules.
|
|
29
29
|
install the npm package and run via bun or node instead:
|
|
30
30
|
npm i -g sootsim && sootsim ${t}
|
|
31
|
-
`),process.exit(1))}var o=T(process.argv);{let{trackCliEvent:t}=await import("./chunks/telemetry-
|
|
31
|
+
`),process.exit(1))}var o=T(process.argv);{let{trackCliEvent:t}=await import("./chunks/telemetry-73Z4FAUH.js");t({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(t){let{flushCliTelemetry:e}=await import("./chunks/telemetry-73Z4FAUH.js");await e(),process.exit(t)}if(o.version){let{readFileSync:t}=await import("fs"),{fileURLToPath:e}=await import("url"),i=e(import.meta.resolve("sootsim/package.json")),m=JSON.parse(t(i,"utf8")),{IS_BETA:I,BETA_LABEL:y}=await import("./chunks/beta-2LIEPFEJ.js"),D=I?` \xB7 ${y}`:"";console.log(`sootsim v${m.version}${D}`);let{readActiveRuntime:N}=await import("./chunks/home-paths-TENEFM4L.js"),b=N();console.log(b?`runtime v${b}`:"runtime not installed"),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,H=o.globalFlags.driver,Q=o.globalFlags.headless===!0,$=o.globalFlags.sim,n=$?["--sim",$,...o.commandArgs]:o.commandArgs;if(d||f){let{settingsStore:t}=await import("./chunks/store-GI3SJOKH.js"),e={};d&&(e.deviceModel=d),f&&(e.colorScheme=f),t.apply(e)}if(!o.command&&o.commandArgs.length===0){let{runStart:t}=await import("./chunks/start-24EAF2KS.js");await t([],{port:a}),await c(0)}var r=o.command??"";if(!r){if(o.commandArgs.length>0){let t=o.commandArgs.find(e=>!e.startsWith("-"))??o.commandArgs[0];console.error(` unknown command: ${t}`),console.error(" run `sootsim --help` to see the full surface."),await c(1)}g(),await c(0)}if(r in u){let t=u[r],e=o.commandArgs.length>0?` ${o.commandArgs.join(" ")}`:"";console.error(` \`sootsim ${r}\` was removed. use \`${t}\` instead.`),e&&console.error(` \u2192 ${t}${e}`),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 t=r==="do"||r==="get"||r==="debug"||r==="shell"||r==="wait",e=o.commandArgs.find(i=>!i.startsWith("-"));r==="shell"||(t&&!e?O(r)&&await c(0):(h(t&&e?e:r),await c(0)))}F(r);if(C.has(r)){let{ensureSootsimReady:t,resolveBootstrapPort:e}=await import("./chunks/auto-bootstrap-7BJDOYUU.js"),i=e(n,a);await t(i);let{runInspect:m}=await import("./chunks/inspect-IWMH6MUT.js");await m([r,...n],{port:i,verbose:s})}else switch(r){case"assert":{let{runAssert:t}=await import("./chunks/assert-7GHUOGLI.js");await t(o.commandArgs);break}case"flow":{let{runFlow:t}=await import("./chunks/flow-TCG5XPDK.js"),e=await t(n);process.exit(typeof e=="number"?e:0)}case"test":{let{runTest:t}=await import("./chunks/test-AJBULIVR.js");await t(o.commandArgs,{port:a,verbose:s});break}case"detox":{let{runDetox:t}=await import("./chunks/detox-4NXKQ2CS.js");await t(o.commandArgs,{port:a,verbose:s});break}case"maestro":{let{runMaestro:t}=await import("./chunks/maestro-552237HC.js"),e=await t(o.commandArgs,{port:a,verbose:s});process.exit(typeof e=="number"?e:0)}case"preview":{let{runPreview:t}=await import("./chunks/preview-GKIGPZUO.js");await t(o.commandArgs,{port:a,verbose:s});break}case"record":{let{runRecord:t}=await import("./chunks/record-FLWDPJIP.js");await t(n,{port:a,verbose:s});break}case"profile":{let{runProfile:t}=await import("./chunks/profile-U64JPCPD.js"),e=await t(o.commandArgs,{port:a,verbose:s});process.exit(typeof e=="number"?e:0)}case"cpu-profile":{let{runCpuProfile:t}=await import("./chunks/cpu-profile-MBYPGUJH.js"),e=await t(n,{port:a,verbose:s});process.exit(typeof e=="number"?e:0)}case"react":{let{runReact:t}=await import("./chunks/react-FWSV5JH2.js"),e=await t(n,{port:a,verbose:s});process.exit(typeof e=="number"?e:0)}case"screenshot":{let{runScreenshot:t}=await import("./chunks/screenshot-4P3TL7CN.js");await t(n,{port:a,verbose:s});break}case"screenshots":{let{runScreenshots:t}=await import("./chunks/screenshots-5HSLPDWZ.js"),e=await t(n,{port:a,verbose:s});process.exit(typeof e=="number"?e:0)}case"screenshot-mode":{let{runScreenshotMode:t}=await import("./chunks/screenshot-mode-GX3Q3IZ6.js");await t(o.commandArgs,{port:a,verbose:s});break}case"three-mode":case"3d-mode":{let{runThreeMode:t}=await import("./chunks/three-mode-JBZSQQIQ.js");await t(o.commandArgs,{port:a,verbose:s});break}case"inspect":{let{runInspect:t}=await import("./chunks/inspect-IWMH6MUT.js");await t(n,{port:a,verbose:s});break}case"debug":{let{runDebug:t}=await import("./chunks/debug-POCRM56I.js");await t(n,{port:a,verbose:s});break}case"timeline":{let{runTimeline:t}=await import("./chunks/timeline-VVGWQSVU.js");await t(n,{port:a,verbose:s});break}case"what-happened":{let{runWhatHappened:t}=await import("./chunks/what-happened-STVD3KZ2.js");await t(n,{port:a,verbose:s});break}case"diagnose":{let{runDiagnose:t}=await import("./chunks/diagnose-IMXDGRVA.js"),e=await t(n,{port:a,verbose:s});process.exit(typeof e=="number"?e:0)}case"open":{let{ensureSootsimReady:t,resolveBootstrapPort:e}=await import("./chunks/auto-bootstrap-7BJDOYUU.js"),i=e(n,a);await t(i);let{runOpenCommand:m}=await import("./chunks/control-HJ2RPHYO.js");await m(n,{port:i});break}case"use":case"focus":{let{runUseCommand:t}=await import("./chunks/control-HJ2RPHYO.js");await t(n,{port:a});break}case"claim":{let{runClaimCommand:t}=await import("./chunks/control-HJ2RPHYO.js");await t(n,{port:a});break}case"close":{let{runCloseCommand:t}=await import("./chunks/control-HJ2RPHYO.js");await t(n,{port:a});break}case"config":{let{runConfig:t}=await import("./chunks/config-OXHJXY6N.js");await t(o.commandArgs);break}case"device":{let{runDeviceCommand:t}=await import("./chunks/device-DURJHKK5.js");await t(n,{port:a});break}case"scan":case"compat":{let{runCompat:t}=await import("./chunks/compat-GWIATWPP.js");await t(o.commandArgs);break}case"electron":{let{runElectron:t}=await import("./chunks/electron-NGWA52N6.js");await t(o.commandArgs,{port:a,device:d,driver:H});break}case"login":{let{runLogin:t}=await import("./chunks/login-AWT3GU5M.js");await t(o.commandArgs);break}case"logout":{let{runLogout:t}=await import("./chunks/logout-R2RUNXHO.js");await t();break}case"whoami":{let{runWhoami:t}=await import("./chunks/whoami-L62IGS4U.js");await t();break}case"keys":{let{runKeys:t}=await import("./chunks/keys-NET26VLH.js");await t(o.commandArgs);break}case"setup-repo":{let{runSetupRepo:t}=await import("./chunks/setup-repo-NQVN5PK7.js");await t(o.commandArgs);break}case"install":{let{runInstall:t}=await import("./chunks/install-IKBAY4PQ.js");await t(o.commandArgs);break}case"install-desktop":{let{runInstallDesktop:t}=await import("./chunks/install-desktop-ABAWCLFJ.js");await t(o.commandArgs);break}case"server":{let{runServer:t}=await import("./chunks/server-Q3ZD4BEF.js");await t(o.commandArgs,{port:a});break}case"daemon":{let{runDaemon:t}=await import("./chunks/daemon-3N3QWMFU.js");await t(o.commandArgs,{port:a});break}case"runtime":{let{runRuntime:t}=await import("./chunks/runtime-AGNC2TK6.js");await t(o.commandArgs);break}case"upgrade":{let{runUpgrade:t}=await import("./chunks/upgrade-IOGHQT7J.js");await t(o.commandArgs);break}case"launch":{let{runLaunch:t}=await import("./chunks/launch-TKIA4RC4.js");await t(o.commandArgs);break}case"start":{let{runStart:t}=await import("./chunks/start-24EAF2KS.js");await t(o.commandArgs,{port:a});break}case"agent":{let{runAgentCommand:t}=await import("./chunks/agent-4BBZUWD2.js"),e=await t(o.commandArgs);process.exit(e)}case"agent-wrapper":{let{runAgentWrapper:t}=await import("./chunks/agent-wrapper-TA5GG3MV.js"),e=await t(o.commandArgs);process.exit(e)}case"skills":{let{runSkills:t}=await import("./chunks/skills-M2CWX5ZC.js");await t(o.commandArgs);break}case"upload":{let{runUpload:t}=await import("./chunks/upload-Z4PPGOX6.js");await t(o.commandArgs,{port:a,verbose:s});break}case"hints":{let{runHints:t}=await import("./chunks/hints-5UNZ7BR2.js");t(o.commandArgs);break}default:console.error(` unknown command: ${r}`),console.error(" run `sootsim --help` to see the full surface."),process.exit(1)}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
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-
|
|
1
|
+
/*! sootsim v0.1.42 | (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-DNSKIJSB.js";import"./chunk-FDB3P2GV.js";import"./chunk-EZGUKWD5.js";import"./chunk-6MYXKMLG.js";import"./chunk-UY6HKNEV.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,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{b as M}from"./chunk-
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{b as M}from"./chunk-FDB3P2GV.js";import"./chunk-UY6HKNEV.js";import{execFile as G,spawn as q}from"node:child_process";import{randomUUID as X}from"node:crypto";import{constants as R,createReadStream as Y,createWriteStream as j,existsSync as I,openSync as J}from"node:fs";import V from"node:fs/promises";import z from"node:path";import K from"node:readline";import{promisify as Q}from"node:util";import{spawn as H}from"node:child_process";import L from"node:readline";var b=class extends Error{code;data;constructor(t,r,m){super(t),this.name="CodexRpcError",this.code=r,this.data=m}};function W(d){let t=H(d.bin,["app-server"],{cwd:d.cwd,env:{...process.env,...d.env},stdio:["pipe","pipe","pipe"]}),r=new Map,m=new Map,u=1,g=!1,a=new Promise(s=>{t.on("exit",(i,e)=>{g=!0;let p=new Error(`codex app-server exited (code=${i}, signal=${e??""})`);for(let{reject:f}of r.values())f(p);r.clear(),s({code:i,signal:e})})});L.createInterface({input:t.stdout,crlfDelay:1/0}).on("line",s=>{let i=s.trim();if(!i)return;let e;try{e=JSON.parse(i)}catch{return}if(e.id!=null&&(e.result!==void 0||e.error!==void 0)){let p=typeof e.id=="string"?Number(e.id):e.id,f=p!=null?r.get(p):void 0;if(!f)return;r.delete(p),e.error?f.reject(new b(e.error.message,e.error.code,e.error.data)):f.resolve(e.result);return}if(e.method){let p=m.get(e.method);if(!p)return;for(let f of p)try{f(e.params)}catch(l){console.error(`[codex-client] handler for "${e.method}" threw:`,l instanceof Error?l.stack??l.message:l)}}}),t.stderr.setEncoding("utf8"),t.stderr.on("data",s=>{let i=m.get("__stderr__");if(i)for(let e of i)try{e({text:s})}catch{}});function n(s){if(!g)try{t.stdin.write(JSON.stringify(s)+`
|
|
3
3
|
`)}catch{}}return{exited:a,on(s,i){let e=m.get(s);return e||(e=new Set,m.set(s,e)),e.add(i),()=>{e?.delete(i)}},request(s,i){if(g)return Promise.reject(new Error(`codex app-server closed; cannot call ${s}`));let e=u++;return new Promise((p,f)=>{r.set(e,{resolve:l=>p(l),reject:f,method:s}),n({jsonrpc:"2.0",id:e,method:s,params:i})})},notify(s,i){n({jsonrpc:"2.0",method:s,params:i})},async shutdown(s=1500){if(g)return;try{t.stdin.end()}catch{}let i=setTimeout(()=>{if(!g)try{t.kill("SIGTERM")}catch{}},s);try{await a}finally{clearTimeout(i)}},kill(s="SIGTERM"){if(!g)try{t.kill(s)}catch{}}}}var O="never",F="danger-full-access",Z={type:"dangerFullAccess"},D="fast",ee="medium",te=Q(G);async function ne(d,t){let r=t||d;if(r.includes("/")||r.includes("\\"))return I(r)?{ok:!0,path:r}:{ok:!1,message:`agent binary not found at path: ${r}`};try{let{stdout:m}=await te("which",[r],{timeout:1500}),u=m.trim();return u?{ok:!0,path:u}:{ok:!1,message:`${r} not found on PATH`}}catch{return{ok:!1,message:`${r} not found on PATH. install the ${d} CLI and retry, or pass --${d}-bin /path/to/${d} to agent start.`}}}function re(d){let t={"--session-id":"sessionId","--project-id":"projectId","--provider":"provider","--cwd":"cwd","--prompt-in":"promptIn","--events-out":"eventsOut","--transcript":"transcript","--codex-bin":"codexBin","--claude-bin":"claudeBin","--claude-session-uuid":"claudeSessionUuid"},r={};for(let m=0;m<d.length;m++){let u=d[m];if(u==="--fresh-thread"){r.freshThread=!0;continue}let g=t[u];g&&(r[g]=d[m+1],m++)}return r}async function Ie(d){let t=re(d);if(!t.sessionId||!t.projectId||!t.provider||!t.cwd||!t.promptIn||!t.eventsOut)return process.stderr.write(`usage: sootsim agent-wrapper --session-id <id> --project-id <id>
|
|
4
4
|
--provider codex|claude --cwd <path>
|
|
5
5
|
--prompt-in <fifo> --events-out <fifo>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import"./chunk-
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import"./chunk-UY6HKNEV.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.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a,b,c,d}from"./chunk-EDXBJUHH.js";import"./chunk-76WF7UIG.js";import"./chunk-D5TKAFJ3.js";import"./chunk-EZGUKWD5.js";import"./chunk-6MYXKMLG.js";import"./chunk-UY6HKNEV.js";export{c as ensureDaemonRunning,a as ensureRuntimeInstalled,d as ensureSootsimReady,b as resolveBootstrapPort};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{a as o}from"./chunk-
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as o}from"./chunk-ITQGNQE3.js";import{l as s}from"./chunk-6MYXKMLG.js";import{chmodSync as c,existsSync as a,mkdirSync as l,readFileSync as d,rmSync as p,writeFileSync as h}from"node:fs";import{dirname as g,join as f,resolve as k}from"node:path";function i(){return f(s(),"credentials.json")}function _(){let t=i();if(!a(t))return null;try{let e=JSON.parse(d(t,"utf8"));return e.version!==1||typeof e.apiKey!="string"||!e.apiKey.startsWith("sk_sootsim_")?null:e.apiKey}catch{return null}}function T(t){if(!t.startsWith("sk_sootsim_"))throw new Error("api key must start with sk_sootsim_");let e=i();l(g(k(e)),{recursive:!0}),h(e,JSON.stringify({version:1,apiKey:t,savedAt:new Date().toISOString()},null,2)+`
|
|
3
3
|
`);try{c(e,384)}catch{}}function K(){p(i(),{force:!0})}var m=["ghs_","ghp_","gho_","ghu_","github_pat_"];function y(t){return!!(t&&t.length>=20&&t.length<=256&&m.some(e=>t.startsWith(e)))}function S(){let t=process.env.SOOT_INSTALLATION_TOKEN?.trim(),e=process.env.GITHUB_TOKEN?.trim(),r=t||e;if(!y(r))return null;let n=(process.env.SOOT_REPO||process.env.GITHUB_REPOSITORY||"").trim();if(!n)return null;let u=(process.env.SOOT_INSTALLATION_ID||process.env.GITHUB_APP_INSTALLATION_ID||"").trim();return{kind:"github",token:r,repoId:n,installationId:u||null,source:t?"soot-runner":"github-actions"}}function b(){let t=process.env.SOOTSIM_API_KEY?.trim();if(t&&t.startsWith("sk_sootsim_"))return{kind:"api-key",secret:t,source:"env"};let e=S();if(e)return e;let r=_();if(r)return{kind:"api-key",secret:r,source:"file"};let n=o();return n?.token?{kind:"session",token:n.token,origin:n.origin}:null}function E(t){return t.kind==="api-key"?`Bearer ${t.secret}`:`Bearer ${t.token}`}export{_ as a,T as b,K as c,b as d,E as e};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
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};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{a as s}from"./chunk-
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as s}from"./chunk-ITQGNQE3.js";import{w as o}from"./chunk-6MYXKMLG.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,4 @@
|
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{createInterface as i}from"readline";var c=()=>i({input:process.stdin,output:process.stdout});function s(o){return new Promise(n=>{let r=c();r.question(o,t=>{r.close(),n(t.trim())})})}async function u(o,n=!0){let r=n?"[Y/n]":"[y/N]";if(!process.stdin.isTTY)return console.log(` ${o} ${r} ${n?"y":"n"} (non-interactive)`),n;let t=await s(` ${o} ${r} `);return t===""?n:t.toLowerCase().startsWith("y")}async function a(o,n){console.log(`
|
|
3
|
+
${o}
|
|
4
|
+
`);for(let e=0;e<n.length;e++)console.log(` ${e+1}. ${n[e]}`);if(console.log(),!process.stdin.isTTY)return console.log(` choose [1-${n.length}]: 1 (non-interactive)`),0;let r=await s(` choose [1-${n.length}]: `),t=parseInt(r,10);return t>=1&&t<=n.length?t-1:0}export{u as a,a as b};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
async function y(e){let t=await e.send({type:"evaluate",code:"(async () => await window.__sootsimTest.getNodeCount())()"});return{nodes:typeof t=="number"?t:0}}async function p(e,t=5){let n=await e.send({type:"evaluate",code:`(async () => await window.__sootsimTest.dumpTree(${t}))()`});return{depth:t,tree:n}}async function m(e){let t=await e.send({type:"evaluate",code:"window.location.href"});return{url:typeof t=="string"?t:""}}async function g(e,t){let n=`(async () => {
|
|
3
3
|
const t = window.__sootsimTest
|
|
4
4
|
const mainShell = window.SootSim?.bridges?.mainShell
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{b as bs}from"./chunk-
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{b as bs}from"./chunk-UY6HKNEV.js";var oi=`(async () => {
|
|
3
3
|
try { localStorage.clear() } catch {}
|
|
4
4
|
try { sessionStorage.clear() } catch {}
|
|
5
5
|
try {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
function d(t){let e=t.displayUrl||t.url;return t.status!=null?`${t.method} ${e} -> ${t.status}${t.statusText?` ${t.statusText}`:""}`:t.error?`${t.method} ${e} -> ${t.error}`:`${t.method} ${e}`}async function u(t,e,...o){return t.send({type:"call",path:`__sootsimTest.${e}`,args:o})}async function g(t,e={}){let o=await t.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!o||typeof o!="object")return;let n=Math.max(0,Number(o.errors)||0),s=Math.max(0,Number(o.warnings)||0);if(n===0&&s===0)return;let r=[];if(n>0&&r.push(`${n} console error${n===1?"":"s"}`),s>0&&r.push(`${s} console warning${s===1?"":"s"}`),console.log(`
|
|
3
3
|
console: ${r.join(", ")}`),e.errorsCommand&&console.log(` inspect: ${e.errorsCommand}`),s>0&&e.warningsCommand&&console.log(` inspect: ${e.warningsCommand}`),!e.includeTail||n===0)return;let i=await t.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors?.(5) || []"});if(!(!Array.isArray(i)||i.length===0)){console.log(`
|
|
4
4
|
recent console errors:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
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
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
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)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
import{execFileSync as h,spawn as g}from"child_process";import{existsSync as s,readdirSync as k}from"fs";import{dirname as m,join as l,resolve as a}from"path";import{fileURLToPath as v}from"url";var c;function p(){if(c!==void 0)return c;try{c=m(v(import.meta.resolve("sootsim-engine/package.json")))}catch{c=null}return c}var I="dev.sootsim.simulator";function x(){let n=p();if(!n)return null;let e=l(n,"dist-electron/main.cjs");if(!s(e))return null;let i=D(n);return i?{path:i,platform:process.platform,kind:"dev-electron",engineDir:n}:null}function b(){let n=p();return n?s(l(n,"src-electron/main.ts")):!1}function D(n){let e=n;for(let i=0;i<6;i++){let t=l(e,"node_modules/.bin/electron");if(s(t))return t;let r=m(e);if(r===e)break;e=r}return null}function C(){let n=p(),i=["/Applications/sootsim.app",a(process.env.HOME||"","Applications/sootsim.app"),...n?[a(n,"app/sootsim.app")]:[]].find(t=>s(t));if(i)return{path:i,platform:"darwin",kind:"mac-app"};try{let t=h("mdfind",[`kMDItemCFBundleIdentifier == "${I}"`],{encoding:"utf8",timeout:3e3}).trim();if(t)return{path:t.split(`
|
|
3
3
|
`)[0],platform:"darwin",kind:"mac-app"}}catch{}return null}function f(n){if(!s(n))return null;let e=k(n).filter(i=>i.startsWith("sootsim")&&i.endsWith(".AppImage")).sort().reverse()[0];return e?l(n,e):null}function w(){let n=p(),i=[a(process.env.HOME||"","Applications/sootsim.AppImage"),a(process.env.HOME||"",".local/bin/sootsim.AppImage"),"/opt/sootsim/sootsim.AppImage","/opt/sootsim/sootsim",...n?[a(n,"app/sootsim.AppImage"),a(n,"release/linux-unpacked/sootsim")]:[]].find(r=>s(r));if(i)return{path:i,platform:"linux",kind:i.endsWith(".AppImage")?"linux-appimage":"linux-binary"};let t=n?f(a(n,"app"))||f(a(n,"release")):null;return t?{path:t,platform:"linux",kind:"linux-appimage"}:null}function A(){let n=x();if(n)return n;if(b()){let e=p(),i=l(e,"dist-electron/main.cjs");return s(i)?console.error(` no node_modules/.bin/electron found near ${e}. run \`bun install\`.`):console.error(` dist-electron/main.cjs missing in ${e}.
|
|
4
4
|
run: bun run --cwd packages/sootsim-engine build:electron-main
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as P,c as v,e as A}from"./chunk-D5TKAFJ3.js";import{E as k,F as T}from"./chunk-6MYXKMLG.js";import{WebSocket as w}from"ws";function M(){let e=k();return e&&T(e)?e.bridgePort:7668}var h=class extends Error{lock;constructor(t,s){super(t),this.name="BridgeSimLockedError",this.lock=s}};function O(e){return e==="flag"?"via --sim":e==="saved"?"saved via `sootsim use`":"primary fallback \u2014 no sim pinned"}function N(e,t={}){let s=new Set,l=t.port??M(),c=t.commandTimeoutMs??15e3,o,g="none",b=new Set(t.stripBooleanFlags??[]),p=new Set(t.stripValueFlags??[]);for(let i=0;i<e.length;i++){let a=e[i];if(a==="--port"||a==="-p"){s.add(i),i+1<e.length&&(s.add(i+1),l=Number(e[i+1])),i++;continue}if(a.startsWith("--port=")){s.add(i),l=Number(a.slice(7));continue}if(a==="--timeout"){s.add(i),i+1<e.length&&(s.add(i+1),c=Number(e[i+1])),i++;continue}if(a==="--sim"){s.add(i),i+1<e.length&&(s.add(i+1),o=e[i+1]?.trim()||void 0,g="flag"),i++;continue}if(b.has(a)){s.add(i);continue}p.has(a)&&(s.add(i),i+1<e.length&&s.add(i+1),i++)}if(!o){let i=v();i&&(o=i.trim()||void 0,g="saved")}return{positional:e.filter((i,a)=>!s.has(a)),wsPort:l,simId:o,simIdSource:g,commandTimeoutMs:c}}function W(e,t={}){let s=1,l=t.commandTimeoutMs??15e3,c=new Map,o=new w(`ws://localhost:${e}`),g=t.simId?{key:`sim:${t.simId}`,source:"explicit-sim-id",stable:!0}:P(),b=new Promise((n,r)=>{o.on("open",()=>{try{o.send(JSON.stringify({type:"bridge:hello",id:0,cliIdentityKey:g.key,cliIdentitySource:g.source,cliLabel:t.cliLabel}))}catch{}n()}),o.on("error",d=>{let u=d.message?`: ${d.message}`:"";r(new Error(`could not connect to ws://localhost:${e}${u}`))})}),p=!1,i=!1;function a(n,r){if(i||process.env.SOOTSIM_QUIET_TARGET_NOTICE==="1"||n.startsWith("bridge:")||n==="focus"||n==="close")return;i=!0;let d=r??"primary",u=O(r?t.simIdSource:"none");process.stderr.write(` \u2192 ${d} (${u})
|
|
3
|
+
`)}return o.on("message",n=>{let r;try{r=JSON.parse(n.toString())}catch{return}if(r.id===0)return;let d=c.get(r.id);d&&(c.delete(r.id),r.i>0&&!p&&(p=!0,process.stderr.write(`
|
|
4
|
+
\u26A0 ${r.i} other CLI identity/identities are driving this sim
|
|
5
|
+
taps, scrolls, and keyboard input from multiple agents will collide on
|
|
6
|
+
the same screen state (this is not a bridge throughput limit).
|
|
7
|
+
use \`sootsim open --new\` for an isolated sim per agent.
|
|
8
|
+
|
|
9
|
+
`)),r.error?r.o?d.reject(new h(r.error,r.o)):d.reject(new Error(r.error)):d.resolve(r.result))}),o.on("close",(n,r)=>{let d=r?.toString()||"connection closed";for(let[u,m]of c)c.delete(u),m.reject(new Error(`sim disconnected: ${d} (code ${n})`))}),{async send(n,r){let d=r?.timeoutMs??l,u=async m=>{await b;let f=s++;return new Promise((C,S)=>{let B=setTimeout(()=>{c.delete(f),S(new Error(`command timed out after ${Math.round(d/1e3)}s`))},d);c.set(f,{resolve:I=>{clearTimeout(B),C(I)},reject:I=>{clearTimeout(B),S(I)}});let y={...n,id:f};y.simId===void 0&&m&&(y.simId=m),a(n.type??"",y.simId),o.send(JSON.stringify(y))})};try{return await u(t.simId)}catch(m){let f=m instanceof Error?m.message:String(m);if(t.fallbackOnMissingSimId&&t.simId&&n.simId===void 0&&f===`no sim connected with id ${t.simId}`)return A(),process.stderr.write(` \u26A0 saved sim ${t.simId} is gone \u2014 falling back to primary
|
|
10
|
+
pin a sim with: sootsim use <sim>
|
|
11
|
+
`),i=!1,u(void 0);throw m}},async listSims(){let n=await this.send({type:"bridge:list-sims"});return Array.isArray(n)?n:[]},async openUrl(n,r={}){return this.send({type:"bridge:open",url:n,newWindow:r.newWindow===!0})},async focusSim(n){return this.send({type:"focus",simId:n})},async closeSim(n){return this.send({type:"close",simId:n})},async claim(n,r={}){return await this.send({type:"bridge:claim",simId:n,force:r.force===!0})},close(){try{o.readyState===w.OPEN&&o.send(JSON.stringify({type:"bridge:bye",id:0}))}catch{}o.close();let n=setTimeout(()=>{o.readyState!==w.CLOSED&&o.terminate()},250)}}}function R(e){return W(e.wsPort,{commandTimeoutMs:e.commandTimeoutMs,simId:e.simId,fallbackOnMissingSimId:e.simIdSource==="saved",simIdSource:e.simIdSource})}async function _(e){try{return await e.send({type:"evaluate",code:"document.hidden"})===!0?(process.stderr.write(`
|
|
12
|
+
\u26A0 target sim is hidden (document.hidden = true)
|
|
13
|
+
animations and rAF callbacks are throttled \u2014 coordinates may be wrong
|
|
14
|
+
and launch/transition animations will not complete.
|
|
15
|
+
bring the sim to the foreground or use: sootsim debug eval "window.focus()"
|
|
16
|
+
|
|
17
|
+
`),{hidden:!0,warned:!0}):{hidden:!1,warned:!1}}catch{return{hidden:!1,warned:!1}}}async function D(e,t,s={}){let l={type:"evaluate",code:t};return s.acquireLock&&(l.acquireLock=!0),e.send(l)}async function j(e,t,...s){return e.send({type:"call",path:t,args:s})}async function q(e,t,...s){return e.send({type:"call",path:t,args:s,acquireLock:!0})}export{M as a,h as b,N as c,W as d,R as e,_ as f,D as g,j as h,q as i};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as p}from"./chunk-BBRAYGDX.js";import{d as c,e as l}from"./chunk-2GKZS2ZZ.js";import{a}from"./chunk-ITQGNQE3.js";async function g(e,t){if(t)return t.replace(/\/$/,"");if(e.kind==="session"&&e.origin)return e.origin.replace(/\/$/,"");let i=a();return i?.origin?i.origin.replace(/\/$/,""):(await p()).replace(/\/$/,"")}async function m(e,t={}){let i=c();if(i||(process.stderr.write(`
|
|
3
|
+
sootsim ${e} needs auth before it can check recording access.
|
|
4
|
+
|
|
5
|
+
pick one:
|
|
6
|
+
\u2022 run \`sootsim login\`
|
|
7
|
+
\u2022 set SOOTSIM_API_KEY=sk_sootsim_... (recommended for CI)
|
|
8
|
+
\u2022 save a personal key with \`sootsim keys use sk_sootsim_...\`
|
|
9
|
+
|
|
10
|
+
`),process.exit(1)),i.kind==="github"&&t.allowGitHubAuth)return;let s=await g(i,t.originOverride),r;try{r=await fetch(`${s}/api/sootsim/billing/subscription`,{headers:{authorization:l(i)}})}catch(n){process.stderr.write(`
|
|
11
|
+
sootsim ${e} couldn't verify recording access.
|
|
12
|
+
${n instanceof Error?n.message:String(n)}
|
|
13
|
+
|
|
14
|
+
`),process.exit(1)}if(r.status===401&&(process.stderr.write(`
|
|
15
|
+
sootsim ${e} couldn't verify recording access with the current auth against ${s}.
|
|
16
|
+
sign in again for that origin, or provide a valid SOOTSIM_API_KEY.
|
|
17
|
+
|
|
18
|
+
`),process.exit(1)),!r.ok){let n=await r.text().catch(()=>"");process.stderr.write(`
|
|
19
|
+
sootsim ${e} couldn't verify recording access (${r.status}).
|
|
20
|
+
${n||"unexpected billing response"}
|
|
21
|
+
|
|
22
|
+
`),process.exit(1)}let o=await r.json();if(o.entitlements?.desktopRecording===!0)return;let u=o.plan??"free";process.stderr.write(`
|
|
23
|
+
sootsim ${e} recording requires Personal, Team, or an active trial.
|
|
24
|
+
current plan: ${u}.
|
|
25
|
+
free keeps basic 3d mode; the trial unlocks the full Personal surface.
|
|
26
|
+
|
|
27
|
+
`),process.exit(1)}export{m as a};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{d as Q,e as X}from"./chunk-
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{d as Q,e as X}from"./chunk-2GKZS2ZZ.js";import{d as J}from"./chunk-DUVJOJTP.js";import{c as q,e as Y,g as w}from"./chunk-76WF7UIG.js";import{a as D,b}from"./chunk-4574AJAK.js";import{a as K}from"./chunk-ITQGNQE3.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
3
|
sootsim upload \u2014 publish the current bundle as a /preview/<id> link
|
|
4
4
|
|
|
5
5
|
usage:
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{b as d}from"./chunk-
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{b as d}from"./chunk-D5TKAFJ3.js";import{existsSync as S,mkdirSync as h,readFileSync as b,writeFileSync as H,rmSync as m}from"fs";import{tmpdir as w}from"os";import{dirname as v,join as p}from"path";var y=new Map;function i(e,r){y.set(e,r)}var a=1;function s(){return p(w(),`sootsim-cli-hints-${d()}.json`)}function l(){return p(w(),"sootsim-cli-hints-global.json")}function u(e){if(!S(e))return{version:a,shown:{}};try{let r=JSON.parse(b(e,"utf8"));return r?.version!==a||!r?.shown?{version:a,shown:{}}:r}catch{return{version:a,shown:{}}}}function f(e,r){try{h(v(e),{recursive:!0}),H(e,JSON.stringify(r)+`
|
|
3
3
|
`)}catch{}}function F(){let e=(process.env.SOOTSIM_HINTS||"").toLowerCase();return e==="off"||e==="0"||e==="false"?"off":e==="always"||e==="verbose"?"always":"normal"}function x(e,r){let o=F();if(o==="off")return!1;if(o==="always"||r==="always")return!0;let n=Date.now();if(r==="once-per-identity"){let t=u(s());return t.shown[e]?!1:(t.shown[e]=n,f(s(),t),!0)}if(r==="once-ever"){let t=u(l());return t.shown[e]?!1:(t.shown[e]=n,f(l(),t),!0)}if(typeof r=="object"&&"cooldownMs"in r){let t=u(s()),c=t.shown[e]??0;return n-c<r.cooldownMs?!1:(t.shown[e]=n,f(s(),t),!0)}return!0}function M(e,...r){let o=y.get(e);if(!o)return process.env.SOOTSIM_HINTS_DEBUG&&console.error(` [hints] no hint registered for id "${e}"`),!1;if(!x(e,o.frequency))return!1;let n=o.render(...r);if(n==null)return!1;let t=Array.isArray(n)?n:[n],c=o.stream==="error"?console.error:console.log;for(let g of t)c(` hint: ${g}`);return!0}function O(){m(s(),{force:!0})}function k(){m(l(),{force:!0})}function T(){return Array.from(y.entries()).map(([e,r])=>({id:e,frequency:r.frequency}))}i("app-still-loading",{frequency:{cooldownMs:6e4},render:e=>`app may still be loading (${e} nodes). run \`sootsim wait ready\` first.`});i("wait-selector-for-missing-testid",{frequency:"once-per-identity",render:e=>`sootsim wait selector ${e}`,stream:"error"});i("prefer-cli-over-eval",{frequency:"once-per-identity",render:e=>e.length?["try the CLI shortcut instead:",...e.map(r=>` ${r}`)]:null,stream:"error"});i("describe-use-filters",{frequency:"once-per-identity",render:()=>["describe output is long. narrow it with:"," sootsim describe --only '*Bottom Sheet*'"," sootsim describe --testid-like 'swap-*'"," sootsim describe --subtree <testID>"]});i("subtree-root-not-found",{frequency:"always",render:e=>`no node with testID/id "${e}" \u2014 try \`sootsim find --testid ${e}\` to discover available ids.`,stream:"error"});export{M as a,O as b,k as c,T as d};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as c,b as p}from"./chunk-6R3CVNXC.js";import{a as m,c as h}from"./chunk-KQN7OUQ6.js";import{a as l,b as u,c as d}from"./chunk-DUVJOJTP.js";function L(){let e=l();return e?{available:!0,reason:null,detail:e}:{available:!1,reason:"no chromium-family browser found (chrome, chromium, edge, brave, arc)"}}async function O(e){if(e.headless)return{launched:!1,message:"the chromium driver launches a visible browser window and cannot run headless \u2014 a headless `chrome --headless=new` process exits immediately and the sim never connects. for headless automation use `--driver playwright`."};let r=l();if(!r)return{launched:!1,message:"chromium not found \u2014 install chrome or run `sootsim list --drivers`"};if(!e.url)return{launched:!1,message:"chromium driver requires a target url"};if(e.profileId||e.ephemeralProfile)return{launched:!1,message:"profiles require electron or playwright; browser tabs use your current Chrome profile"};try{let i=await d(e.url,{detached:e.detached??!0});return{launched:!0,message:`chromium launched \u2192 ${e.url}`,pid:i.pid,target:i.target??r,attachUrl:e.url}}catch(i){return{launched:!1,message:`chromium spawn failed: ${i instanceof Error?i.message:String(i)}`}}}var f={id:"chromium",name:"chromium",description:"system chrome / chromium / edge \u2014 visible window (headless: use playwright)",kind:"browser",availability:L,launch:O};function k(){let e=c();return e?{available:!0,reason:null,detail:`${e.kind} @ ${e.path}`}:{available:!1,reason:"sootsim desktop app not installed (run `sootsim install-desktop`)"}}async function x(e){let r=c();if(!r)return{launched:!1,message:"sootsim desktop app not installed"};try{let i=await p(e.url,r,{device:e.device,profileId:e.profileId,ephemeralProfile:e.ephemeralProfile});return i.launched?{launched:!0,message:e.url?`electron launched via ${i.via} \u2192 ${e.url}`:`electron launched via ${i.via}`,target:i.target,attachUrl:e.url}:{launched:!1,message:"desktop companion failed to start"}}catch(i){return{launched:!1,message:`electron launch failed: ${i instanceof Error?i.message:String(i)}`}}}var v={id:"electron",name:"electron",description:"sootsim desktop companion app (native window, menu bar)",kind:"native",availability:k,launch:x};import{spawn as I}from"child_process";import{closeSync as R,mkdtempSync as A,openSync as $,readFileSync as _,rmSync as U}from"fs";import{createRequire as T}from"module";import{tmpdir as g}from"os";import{join as w}from"path";var E=`
|
|
3
|
+
const modulePath = process.env.SOOTSIM_PW_MODULE;
|
|
4
|
+
const url = process.env.SOOTSIM_PW_URL;
|
|
5
|
+
const headless = process.env.SOOTSIM_PW_HEADLESS === '1';
|
|
6
|
+
const userDataDir = process.env.SOOTSIM_PW_USERDATADIR || '';
|
|
7
|
+
(async () => {
|
|
8
|
+
const pw = require(modulePath);
|
|
9
|
+
let browser = null;
|
|
10
|
+
let context;
|
|
11
|
+
// channel 'chromium' forces the FULL Chromium build. playwright's
|
|
12
|
+
// default \`headless: true\` launches the stripped "headless shell"
|
|
13
|
+
// binary, which omits Web Platform features sootsim debugging relies
|
|
14
|
+
// on (full WebGL / CanvasKit GPU readback in particular). the full
|
|
15
|
+
// build runs headless via Chrome's new headless mode at full feature
|
|
16
|
+
// parity. NOTE: this is NOT enough to make \`sootsim cpu-profile\`
|
|
17
|
+
// work \u2014 that profiles the tenant *worker*, and the JS Self-Profiler
|
|
18
|
+
// API cannot be constructed in a dedicated worker by any means (see
|
|
19
|
+
// worker-handlers/cpu-profile.ts). cpu-profile needs a CDP-based
|
|
20
|
+
// profiler instead.
|
|
21
|
+
const launchOpts = { headless, channel: 'chromium' };
|
|
22
|
+
if (userDataDir) {
|
|
23
|
+
context = await pw.chromium.launchPersistentContext(userDataDir, launchOpts);
|
|
24
|
+
} else {
|
|
25
|
+
browser = await pw.chromium.launch(launchOpts);
|
|
26
|
+
context = await browser.newContext();
|
|
27
|
+
}
|
|
28
|
+
const page = await context.newPage();
|
|
29
|
+
// surface page-side failures (engine boot crash, failed WS registration)
|
|
30
|
+
// to stderr so a sim that never connects produces a real diagnostic
|
|
31
|
+
// instead of a silent "timed out waiting for opened sim to connect".
|
|
32
|
+
page.on('pageerror', (e) => {
|
|
33
|
+
process.stderr.write('[pageerror] ' + ((e && e.stack) || e) + '\\n');
|
|
34
|
+
});
|
|
35
|
+
page.on('console', (m) => {
|
|
36
|
+
if (m.type() === 'error') {
|
|
37
|
+
process.stderr.write('[console.error] ' + m.text() + '\\n');
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
page.on('crash', () => process.stderr.write('[page] renderer crashed\\n'));
|
|
41
|
+
try {
|
|
42
|
+
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });
|
|
43
|
+
} catch (err) {
|
|
44
|
+
process.stderr.write('[goto] ' + String((err && err.message) || err) + '\\n');
|
|
45
|
+
}
|
|
46
|
+
const keepAlive = setInterval(() => {}, 1 << 30);
|
|
47
|
+
const shutdown = () => { clearInterval(keepAlive); process.exit(0); };
|
|
48
|
+
if (browser) browser.on('disconnected', shutdown);
|
|
49
|
+
context.on('close', shutdown);
|
|
50
|
+
page.on('close', () => { context.close().catch(() => {}); });
|
|
51
|
+
})().catch((err) => {
|
|
52
|
+
process.stderr.write(String((err && err.stack) || err) + '\\n');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
});
|
|
55
|
+
`;function y(){try{let e=T(process.cwd()+"/");for(let r of["playwright","playwright-chromium","playwright-core"])try{return{spec:r,modulePath:e.resolve(r)}}catch{}}catch{}return null}function W(){let e=y();return e?{available:!0,reason:null,detail:`resolved via ${e.spec}`}:{available:!1,reason:"playwright not installed in the current workspace"}}function C(e){return e.profileId?m(h(e.profileId).id):e.ephemeralProfile?A(w(g(),"sootsim-playwright-profile-")):""}async function M(e){let r=y();if(!r)return{launched:!1,message:"playwright not installed \u2014 run `bun add -D playwright` first"};if(!e.url)return{launched:!1,message:"playwright driver requires a target url"};let i=w(g(),`sootsim-playwright-host-${Date.now().toString(36)}-${process.pid}.log`),a=$(i,"a");try{let t=I(process.execPath,["-e",E],{detached:!0,stdio:["ignore","ignore",a],env:{...process.env,SOOTSIM_PW_MODULE:r.modulePath,SOOTSIM_PW_URL:e.url,SOOTSIM_PW_HEADLESS:e.headless??!0?"1":"0",SOOTSIM_PW_USERDATADIR:C(e)}});t.unref();let o=await new Promise(n=>{let S=setTimeout(()=>n(null),4e3);t.once("exit",P=>{clearTimeout(S),n(P??0)})});if(o!==null&&o!==0){let n=_(i,"utf8").trim();return U(i,{force:!0}),{launched:!1,message:`playwright host exited early (code ${o})${n?`: ${n.split(`
|
|
56
|
+
`).slice(-3).join(" ")}`:""}`}}return{launched:!0,message:`playwright chromium launched \u2192 ${e.url}`,pid:t.pid,target:r.spec,attachUrl:e.url}}catch(t){return{launched:!1,message:`playwright launch failed: ${t instanceof Error?t.message:String(t)}`}}finally{R(a)}}var D={id:"playwright",name:"playwright",description:"programmatic chromium via the playwright package \u2014 headless default",kind:"automation",availability:W,launch:M};function q(){return process.platform!=="darwin"&&process.platform!=="linux"&&process.platform!=="win32"?{available:!1,reason:`unsupported platform: ${process.platform}`}:{available:!0,reason:null,detail:process.platform==="darwin"?"open(1)":process.platform==="win32"?"cmd /c start":"xdg-open(1)"}}async function H(e){if(e.headless)return{launched:!1,message:"system driver does not support --headless; use chromium or playwright"};if(!e.url)return{launched:!1,message:"system driver requires a target url"};if(e.profileId||e.ephemeralProfile)return{launched:!1,message:"profiles require electron or playwright; browser tabs use your current browser profile"};try{let r=await u(e.url,{detached:e.detached??!0,newWindow:e.newWindow});return{launched:!0,message:`${r.via} launch \u2192 ${e.url}`,pid:r.pid,target:r.target,attachUrl:e.url}}catch(r){return{launched:!1,message:`system launch failed: ${r instanceof Error?r.message:String(r)}`}}}var b={id:"system",name:"system",description:"shared browser launcher \u2014 system default or chromium window",kind:"delegate",availability:q,launch:H};var s=[f,v,D,b];function ae(){return s}function ne(e){return s.find(r=>r.id===e)??null}function se(e,r){if(e)return s.find(a=>a.id===e)??null;for(let i of r){let a=s.find(t=>t.id===i);if(a&&a.availability().available)return a}return null}function oe(){return s.map(e=>{let r=e.availability();return{id:e.id,name:e.name,kind:e.kind,description:e.description,available:r.available,reason:r.reason,detail:r.detail??null}})}export{f as a,v as b,D as c,b as d,s as e,ae as f,ne as g,se as h,oe as i};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
import{readFileSync as i}from"node:fs";import{fileURLToPath as e}from"node:url";var r=null;function l(){if(r!=null)return r;let o=[()=>e(import.meta.resolve("sootsim/package.json")),()=>e(new URL("../package.json",import.meta.url))];for(let n of o)try{let t=JSON.parse(i(n(),"utf8")).version;if(typeof t=="string"&&t)return r=t,r}catch{}return r="0.0.0",r}export{l as a};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.42 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
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
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
4
|
`)}function K(){s(l(),{force:!0})}export{k as a,L as b,J as c,j as d,K as e};
|