sootsim 0.1.138 → 0.1.140

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/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-TD7SHXRH.js → agent-N767ME6M.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-H6JLLQAZ.js → agent-wrapper-ELHIUFZZ.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-JDQFGE3V.js → app-fonts-OZ3OSNAJ.js} +2 -2
  5. package/dist-cli/chunks/{assert-2XLXLJOD.js → assert-GGFUQBNB.js} +2 -2
  6. package/dist-cli/chunks/auto-bootstrap-L5E6XMCK.js +2 -0
  7. package/dist-cli/chunks/beta-D74SDA2L.js +2 -0
  8. package/dist-cli/chunks/camera-5PYEDLLB.js +20 -0
  9. package/dist-cli/chunks/chunk-4FBFOWV3.js +4 -0
  10. package/dist-cli/chunks/{chunk-7ELG4PYE.js → chunk-4FGNOWB6.js} +1 -1
  11. package/dist-cli/chunks/{chunk-ZSPUTLK7.js → chunk-5EP5RRNS.js} +35 -34
  12. package/dist-cli/chunks/{chunk-BA3QQ5B3.js → chunk-5VTYMBUK.js} +2 -2
  13. package/dist-cli/chunks/chunk-6KUVOSFF.js +79 -0
  14. package/dist-cli/chunks/{chunk-CTXIRBH2.js → chunk-77TL74AM.js} +1 -1
  15. package/dist-cli/chunks/{chunk-BDOLDROC.js → chunk-7SMEXHWJ.js} +1 -1
  16. package/dist-cli/chunks/{chunk-JFQVDRBK.js → chunk-AI65UVSN.js} +52 -4
  17. package/dist-cli/chunks/{chunk-XWHR6IKV.js → chunk-AOICEZCA.js} +2 -2
  18. package/dist-cli/chunks/chunk-AP2MOP44.js +2 -0
  19. package/dist-cli/chunks/chunk-BEA3AO36.js +5 -0
  20. package/dist-cli/chunks/{chunk-PILBWKNB.js → chunk-BGXNYXBC.js} +1 -1
  21. package/dist-cli/chunks/{chunk-FFVME5EQ.js → chunk-BLQBPN76.js} +2 -2
  22. package/dist-cli/chunks/{chunk-Q4J2SESV.js → chunk-BM7QWZRI.js} +2 -2
  23. package/dist-cli/chunks/{chunk-5N5MQQM5.js → chunk-C3FURRBF.js} +1 -1
  24. package/dist-cli/chunks/{chunk-RHU73TIJ.js → chunk-CQ3LV5VL.js} +2 -2
  25. package/dist-cli/chunks/chunk-EH6YDCSN.js +119 -0
  26. package/dist-cli/chunks/{chunk-T3HJHXXN.js → chunk-EMNVJOEL.js} +3 -3
  27. package/dist-cli/chunks/{chunk-C563J47N.js → chunk-FYUDIUFX.js} +2 -2
  28. package/dist-cli/chunks/{chunk-WHIZNJLR.js → chunk-GI43DDEI.js} +1 -1
  29. package/dist-cli/chunks/{chunk-KLFGCFE4.js → chunk-GL74P6NR.js} +1 -1
  30. package/dist-cli/chunks/{chunk-GYZ5ZZMH.js → chunk-GYZNLDBX.js} +2 -2
  31. package/dist-cli/chunks/chunk-HPTMLB7V.js +2 -0
  32. package/dist-cli/chunks/{chunk-NPUHFOSG.js → chunk-MRQRJINW.js} +1 -1
  33. package/dist-cli/chunks/{chunk-IEGRNKTT.js → chunk-N2XPC4Z7.js} +2 -2
  34. package/dist-cli/chunks/chunk-NQG4R5K2.js +1 -0
  35. package/dist-cli/chunks/{chunk-62DPZPFC.js → chunk-O2SQNUDP.js} +1 -1
  36. package/dist-cli/chunks/{chunk-I7RL227U.js → chunk-PBS47TD5.js} +2 -2
  37. package/dist-cli/chunks/chunk-Q5Z7P54I.js +2 -0
  38. package/dist-cli/chunks/{chunk-FBDOREAI.js → chunk-QOZ2Q4FH.js} +1 -1
  39. package/dist-cli/chunks/{chunk-SX6BVZL5.js → chunk-QRRBQE6M.js} +2 -2
  40. package/dist-cli/chunks/{chunk-KJOBH5CA.js → chunk-QXOZB7WD.js} +2 -2
  41. package/dist-cli/chunks/{chunk-3XBLSPSH.js → chunk-R5F7XGAO.js} +3 -3
  42. package/dist-cli/chunks/{chunk-VIZ5BLM2.js → chunk-RAY2DLSK.js} +1 -1
  43. package/dist-cli/chunks/{chunk-TP3NTZUM.js → chunk-REIC7HRW.js} +1 -1
  44. package/dist-cli/chunks/chunk-S7I6ZCT2.js +1 -0
  45. package/dist-cli/chunks/{chunk-GSGRNYPC.js → chunk-SSZBFWV7.js} +1 -1
  46. package/dist-cli/chunks/chunk-UHTE6FLK.js +69 -0
  47. package/dist-cli/chunks/{chunk-MZ7TYYP7.js → chunk-WGDXZMKT.js} +2 -2
  48. package/dist-cli/chunks/chunk-WN3WZEE5.js +1 -0
  49. package/dist-cli/chunks/{chunk-JEL7BQG7.js → chunk-X6AWKKL4.js} +2 -2
  50. package/dist-cli/chunks/{chunk-T6QPOIJN.js → chunk-XGYD25DJ.js} +1 -1
  51. package/dist-cli/chunks/{chunk-XV6XIC4J.js → chunk-ZGDJ5TFU.js} +2 -2
  52. package/dist-cli/chunks/{chunk-KBOMW6U3.js → chunk-ZN4Z2W7F.js} +2 -2
  53. package/dist-cli/chunks/{chunk-MNKYCXHQ.js → chunk-ZVQOEMXS.js} +52 -52
  54. package/dist-cli/chunks/cli-version-EZRTEUXF.js +2 -0
  55. package/dist-cli/chunks/{compat-6KRCWKBL.js → compat-U3772TUK.js} +3 -3
  56. package/dist-cli/chunks/{config-JGTLOWS6.js → config-6CZCIYKJ.js} +2 -2
  57. package/dist-cli/chunks/{control-3LHOESUK.js → control-NVA25O65.js} +2 -2
  58. package/dist-cli/chunks/{cpu-profile-KWE5IXBN.js → cpu-profile-WRLTZYO6.js} +2 -2
  59. package/dist-cli/chunks/{daemon-S5LNAQAU.js → daemon-QQPGLGS6.js} +2 -2
  60. package/dist-cli/chunks/{debug-KJ3TNXUN.js → debug-RKYLSDZV.js} +3 -3
  61. package/dist-cli/chunks/{detox-UJIPM47N.js → detox-ZRUQQU22.js} +2 -2
  62. package/dist-cli/chunks/{device-23SEWSUA.js → device-HXTOLEWY.js} +2 -2
  63. package/dist-cli/chunks/{diagnose-53JGSJF2.js → diagnose-QN4E4WA6.js} +2 -2
  64. package/dist-cli/chunks/drivers-EVK22AX5.js +2 -0
  65. package/dist-cli/chunks/{electron-F43274XT.js → electron-ZHRC4WQ5.js} +3 -3
  66. package/dist-cli/chunks/flow-ICCRVJVX.js +2 -0
  67. package/dist-cli/chunks/help-QMZ35MIQ.js +2 -0
  68. package/dist-cli/chunks/{hints-6EFUPUX6.js → hints-HCHKMDUE.js} +2 -2
  69. package/dist-cli/chunks/{home-paths-TAGKOEXO.js → home-paths-3OHKRAE4.js} +2 -2
  70. package/dist-cli/chunks/{inspect-UVBYBYJB.js → inspect-QXUBDKJJ.js} +3 -3
  71. package/dist-cli/chunks/install-JSDZIE2T.js +2 -0
  72. package/dist-cli/chunks/{install-desktop-M2QEFAIN.js → install-desktop-QCX44BGL.js} +7 -7
  73. package/dist-cli/chunks/{keys-IJNQHCGZ.js → keys-VEP2KPUF.js} +2 -2
  74. package/dist-cli/chunks/{launch-UK4I6UYE.js → launch-K4BPQLTP.js} +3 -3
  75. package/dist-cli/chunks/{login-OBLKQALN.js → login-UVC5XRKR.js} +4 -4
  76. package/dist-cli/chunks/{logout-HUOLFAU6.js → logout-3VW34IBA.js} +2 -2
  77. package/dist-cli/chunks/{maestro-B6JMWFEO.js → maestro-HTFXXMLR.js} +2 -2
  78. package/dist-cli/chunks/optional-demo-registry-5YYEAL46.js +2 -0
  79. package/dist-cli/chunks/{preview-TYICI3EN.js → preview-TZYJMLEJ.js} +2 -2
  80. package/dist-cli/chunks/{profile-NQO5HFFJ.js → profile-HDJRF7YB.js} +2 -2
  81. package/dist-cli/chunks/{react-WXEGMAH6.js → react-RLJR26M7.js} +2 -2
  82. package/dist-cli/chunks/{record-3DK7CCXV.js → record-2LDDHHUY.js} +2 -2
  83. package/dist-cli/chunks/runtime-QPYF2WQX.js +2 -0
  84. package/dist-cli/chunks/{runtime-delivery-QAHWI6JH.js → runtime-delivery-3F6O57E5.js} +2 -2
  85. package/dist-cli/chunks/{screenshot-SQ7ETUJY.js → screenshot-QAUSSEPK.js} +2 -2
  86. package/dist-cli/chunks/{screenshot-mode-YYIBQI6S.js → screenshot-mode-K6HEVK4K.js} +2 -2
  87. package/dist-cli/chunks/{screenshots-YH5P24GR.js → screenshots-TWMCGUBT.js} +2 -2
  88. package/dist-cli/chunks/{server-PVYHPTCD.js → server-ZPIZCBW5.js} +3 -3
  89. package/dist-cli/chunks/setup-repo-VHOZJEIV.js +2 -0
  90. package/dist-cli/chunks/{skills-2V2A7R4O.js → skills-NI3RH7CW.js} +2 -2
  91. package/dist-cli/chunks/{start-JKY3T6AY.js → start-G6CQL6HJ.js} +4 -4
  92. package/dist-cli/chunks/store-F6MJUJYW.js +2 -0
  93. package/dist-cli/chunks/telemetry-DM2Y7OQJ.js +2 -0
  94. package/dist-cli/chunks/{test-FVA5WGGM.js → test-V47D6EPK.js} +3 -3
  95. package/dist-cli/chunks/{three-mode-GVODLLP3.js → three-mode-G7N3LRHM.js} +2 -2
  96. package/dist-cli/chunks/{timeline-LCJYWJBG.js → timeline-EBUOILTJ.js} +2 -2
  97. package/dist-cli/chunks/{upgrade-4TVPQJRL.js → upgrade-OQJLTCQP.js} +2 -2
  98. package/dist-cli/chunks/upload-W3YCA65H.js +2 -0
  99. package/dist-cli/chunks/{version-2XWRCYTM.js → version-3YJPPUE5.js} +2 -2
  100. package/dist-cli/chunks/web-ZKUX5ICX.js +2 -0
  101. package/dist-cli/chunks/{what-happened-R57H6WK6.js → what-happened-HOY3TA42.js} +2 -2
  102. package/dist-cli/chunks/{whoami-YCVHJHIM.js → whoami-GOCSBVTG.js} +2 -2
  103. package/dist-lib/agent-daemon-client.cjs +1 -1
  104. package/dist-lib/agent-events.cjs +1 -1
  105. package/dist-lib/agent-sessions.cjs +1 -1
  106. package/dist-lib/attached-projects.cjs +42 -820
  107. package/dist-lib/auth/shared-session.cjs +1 -1
  108. package/dist-lib/backend-origin.cjs +1 -1
  109. package/dist-lib/beta.cjs +1 -1
  110. package/dist-lib/beta.mjs +1 -1
  111. package/dist-lib/bridge-constants.cjs +1 -1
  112. package/dist-lib/cli-constants.cjs +1 -1
  113. package/dist-lib/config.cjs +1 -1
  114. package/dist-lib/detox/index.cjs +1 -1
  115. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  116. package/dist-lib/home-paths.cjs +1 -1
  117. package/dist-lib/host/bridge-host.cjs +179 -956
  118. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  119. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  120. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  121. package/dist-lib/host/websocket-proxy.cjs +1 -1
  122. package/dist-lib/index.cjs +1 -1
  123. package/dist-lib/metro.cjs +1 -1
  124. package/dist-lib/profiles.cjs +1 -1
  125. package/dist-lib/render-mode.cjs +1 -1
  126. package/dist-lib/scripts/dev-server-scanner.cjs +29 -797
  127. package/dist-lib/sdk.cjs +1 -1
  128. package/dist-lib/sdk.mjs +1 -1
  129. package/dist-lib/skills.cjs +660 -1032
  130. package/dist-lib/vite.cjs +1 -1
  131. package/package.json +2 -6
  132. package/scripts/dev-server-scanner.ts +10 -2
  133. package/scripts/optional-demo-registry.ts +54 -0
  134. package/src/attached-projects.ts +6 -27
  135. package/dist-cli/chunks/auto-bootstrap-Q7Z5522T.js +0 -2
  136. package/dist-cli/chunks/beta-LW4TRSKL.js +0 -2
  137. package/dist-cli/chunks/chunk-3AVKOCIL.js +0 -5
  138. package/dist-cli/chunks/chunk-BXITI3GQ.js +0 -4
  139. package/dist-cli/chunks/chunk-DBJCMZX7.js +0 -1
  140. package/dist-cli/chunks/chunk-DV4DKAHB.js +0 -64
  141. package/dist-cli/chunks/chunk-KYAAYSMS.js +0 -2
  142. package/dist-cli/chunks/chunk-M6GZUJXH.js +0 -62
  143. package/dist-cli/chunks/chunk-N4DFR7UX.js +0 -79
  144. package/dist-cli/chunks/chunk-N7TXV2XT.js +0 -1
  145. package/dist-cli/chunks/chunk-SIKDBA2E.js +0 -119
  146. package/dist-cli/chunks/chunk-YB7NANNJ.js +0 -1
  147. package/dist-cli/chunks/chunk-ZS55UGAA.js +0 -2
  148. package/dist-cli/chunks/cli-version-ROECZHPK.js +0 -2
  149. package/dist-cli/chunks/demo-app-registry-SU74KYFQ.js +0 -2
  150. package/dist-cli/chunks/drivers-LQS4T2IT.js +0 -2
  151. package/dist-cli/chunks/flow-H4F2X23Y.js +0 -2
  152. package/dist-cli/chunks/help-BT5NJNJ5.js +0 -2
  153. package/dist-cli/chunks/install-P5R6747T.js +0 -2
  154. package/dist-cli/chunks/runtime-IFNZGBPZ.js +0 -2
  155. package/dist-cli/chunks/setup-repo-Y63FUXRC.js +0 -2
  156. package/dist-cli/chunks/store-KNRC4EGM.js +0 -2
  157. package/dist-cli/chunks/telemetry-HDSITSDA.js +0 -2
  158. package/dist-cli/chunks/upload-3AXP6K6R.js +0 -2
  159. package/dist-cli/chunks/web-4Z6SFQFV.js +0 -2
  160. package/dist-lib/scripts/demo-app-registry.cjs +0 -818
  161. package/scripts/demo-app-registry.ts +0 -1006
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.140 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sootsim",
3
- "version": "0.1.138",
3
+ "version": "0.1.140",
4
4
  "description": "sootsim CLI + vite/metro plugins + skills registry. bridge client for driving the proprietary sootsim-engine over WebSocket.",
5
5
  "author": "Tamagui LLC",
6
6
  "license": "MIT",
@@ -109,10 +109,6 @@
109
109
  "source": "./scripts/dev-server-scanner.ts",
110
110
  "default": "./dist-lib/scripts/dev-server-scanner.cjs"
111
111
  },
112
- "./scripts/demo-app-registry": {
113
- "source": "./scripts/demo-app-registry.ts",
114
- "default": "./dist-lib/scripts/demo-app-registry.cjs"
115
- },
116
112
  "./detox": {
117
113
  "source": "./detox/index.ts",
118
114
  "default": "./dist-lib/detox/index.cjs"
@@ -131,7 +127,7 @@
131
127
  "dist-lib/",
132
128
  "src/",
133
129
  "scripts/dev-server-scanner.ts",
134
- "scripts/demo-app-registry.ts",
130
+ "scripts/optional-demo-registry.ts",
135
131
  "detox/",
136
132
  "scripts/postinstall.cjs",
137
133
  "README.md",
@@ -21,7 +21,15 @@ import { promisify } from 'util'
21
21
  const execP = promisify(exec)
22
22
  import { applySootSimConfigToUrl } from '../src/config.ts'
23
23
  import { normalizeNativeDevBundleUrl } from '../src/native-dev-bundle-url.ts'
24
- import { APPS } from './demo-app-registry.ts'
24
+ import { loadOptionalDemoApps, optionalDemoAppsSync } from './optional-demo-registry.ts'
25
+
26
+ // pre-warm the optional internal demo registry once at module load. in-repo
27
+ // (electron tray / `bun run demo` discovery) this resolves the source registry
28
+ // so a launched demo's runtimeConfig is folded into its bundle URL; on a
29
+ // published install the registry was never shipped, so this resolves to [] and
30
+ // every dev server is treated generically. either way `withRuntimeConfig` below
31
+ // reads the synchronous cached view.
32
+ void loadOptionalDemoApps()
25
33
 
26
34
  export interface DiscoveredServer {
27
35
  port: number
@@ -261,7 +269,7 @@ function makeResult(
261
269
  }
262
270
 
263
271
  function withRuntimeConfig(port: number, bundleUrl: string): string {
264
- const knownApp = APPS.find((app) => app.preferredPort === port)
272
+ const knownApp = optionalDemoAppsSync().find((app) => app.preferredPort === port)
265
273
  const configured = knownApp?.runtimeConfig
266
274
  ? applySootSimConfigToUrl(bundleUrl, knownApp.runtimeConfig)
267
275
  : bundleUrl
@@ -0,0 +1,54 @@
1
+ // optional, best-effort access to the INTERNAL demo-app registry
2
+ // (`./demo-app-registry.ts`). that file is repo-internal dev tooling: it pins
3
+ // real demo apps to fixed ports (e.g. 3pc on 8081) and is consumed only by
4
+ // `bun run demo` + the in-repo electron/vite discovery paths, which run from
5
+ // the typescript source where the registry is always present.
6
+ //
7
+ // the PUBLISHED `sootsim` npm package must know nothing about those internal
8
+ // apps — shipping the registry once matched a brand-new user's `expo start` on
9
+ // the default port 8081 against the 3pc `one` entry and crashed their metro
10
+ // (repo-agnostic-pipeline violation). so the registry is NOT in the package
11
+ // `files` list and is marked external in `scripts/build-cli.ts`, which leaves
12
+ // this `import()` as a runtime dynamic import: it resolves the source registry
13
+ // in-repo and resolves to nothing (empty list) on a published install.
14
+ //
15
+ // one path, no env toggle: every consumer goes through this loader; whether the
16
+ // registry resolves is purely a function of whether the file exists on disk.
17
+
18
+ // the path is assembled at runtime so neither esbuild nor a bundler treats it
19
+ // as a static dependency to inline — it stays a true dynamic import resolved
20
+ // against the package's own scripts dir at runtime.
21
+ const REGISTRY_SPECIFIER = './demo-app-registry.ts'
22
+
23
+ export interface OptionalDemoApp {
24
+ name: string
25
+ label: string
26
+ dir: string
27
+ preferredPort: number
28
+ framework: 'expo' | 'one' | 'rock'
29
+ runtimeConfig?: import('../src/config.ts').SootSimConfig
30
+ }
31
+
32
+ let cached: OptionalDemoApp[] | null = null
33
+
34
+ /** load the internal demo registry if it's present on disk (in-repo only).
35
+ * returns [] on a published install where the registry was not shipped. */
36
+ export async function loadOptionalDemoApps(): Promise<OptionalDemoApp[]> {
37
+ if (cached) return cached
38
+ try {
39
+ const mod = (await import(/* @vite-ignore */ REGISTRY_SPECIFIER)) as {
40
+ APPS?: OptionalDemoApp[]
41
+ }
42
+ cached = Array.isArray(mod.APPS) ? mod.APPS : []
43
+ } catch {
44
+ cached = []
45
+ }
46
+ return cached
47
+ }
48
+
49
+ /** synchronous view of the registry — empty until `loadOptionalDemoApps()` has
50
+ * resolved at least once. the scanner pre-warms this at module init so its
51
+ * synchronous per-port lookup can stay synchronous. */
52
+ export function optionalDemoAppsSync(): OptionalDemoApp[] {
53
+ return cached ?? []
54
+ }
@@ -483,33 +483,12 @@ export function deletePreviewAttachment(id: string): void {
483
483
  export async function seedFromDemoAppRegistry(): Promise<void> {
484
484
  const existing = loadStore().attachedProjects
485
485
  if (existing.length > 0) return
486
- let APPS: unknown
487
- try {
488
- const mod = (await import('../scripts/demo-app-registry')) as {
489
- APPS: Array<{
490
- name: string
491
- label: string
492
- dir: string
493
- preferredPort: number
494
- framework: 'expo' | 'one' | 'rock'
495
- }>
496
- }
497
- APPS = mod.APPS
498
- } catch (err) {
499
- console.warn(
500
- '[sootsim] seedFromDemoAppRegistry: could not load demo registry:',
501
- (err as Error).message,
502
- )
503
- return
504
- }
505
- if (!Array.isArray(APPS)) return
506
- const apps = APPS as Array<{
507
- name: string
508
- label: string
509
- dir: string
510
- preferredPort: number
511
- framework: 'expo' | 'one' | 'rock'
512
- }>
486
+ // optional internal-only registry — resolves to [] on a published install
487
+ // (the registry is not shipped), so this seed is a no-op for real users and
488
+ // never pins their ports to internal demo apps.
489
+ const { loadOptionalDemoApps } = await import('../scripts/optional-demo-registry')
490
+ const apps = await loadOptionalDemoApps()
491
+ if (apps.length === 0) return
513
492
  mutateStore((store) => {
514
493
  for (const app of apps) {
515
494
  if (!fs.existsSync(app.dir)) continue
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c,d}from"./chunk-3XBLSPSH.js";import"./chunk-XWHR6IKV.js";import"./chunk-VIZ5BLM2.js";import"./chunk-FBDOREAI.js";import"./chunk-KLFGCFE4.js";import"./chunk-62DPZPFC.js";export{c as ensureDaemonRunning,a as ensureRuntimeInstalled,d as ensureSootsimReady,b as resolveBootstrapPort};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c,d,e}from"./chunk-PILBWKNB.js";import"./chunk-62DPZPFC.js";export{e as BETA_ASK_HEADLINE,c as BETA_LABEL,d as BETA_TAGLINE,b as BETA_VERSION_TARGET,a as IS_BETA};
@@ -1,5 +0,0 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as R}from"./chunk-DV4DKAHB.js";var C="sootsimConfig";function m(e){return!!e&&Object.keys(e).length>0}function U(e){return e?m(e.modules)||m(e.turboModules)||m(e.nativeModules)||m(e.env)||m(e.settings)||m(e.initialState):!1}function x(e,r){let t=new URL(e);return U(r)?t.searchParams.set(C,JSON.stringify(r)):t.searchParams.delete(C),t.toString()}import{exec as E}from"child_process";import A from"http";import N from"net";import{promisify as L}from"util";var ee="/index.bundle?platform=ios&dev=true&hot=true&minify=false";function _(e){return/^https?:\/\//i.test(e)}function D(e){return e.endsWith(".bundle")}function T(e){process.env.SOOTSIM_PREVIEW_PROD_BUNDLE&&(e.searchParams.set("dev","false"),e.searchParams.set("minify","true"),e.searchParams.has("hot")&&e.searchParams.set("hot","false"))}function k(e){try{let r=_(e),t=new URL(e,"http://soot.local");return t.pathname=t.pathname.replace(/\.\.bundle$/,".bundle"),D(t.pathname)?(t.searchParams.delete("transform.bytecode"),T(t),r?t.toString():`${t.pathname}${t.search}${t.hash}`):e}catch{return e}}var v=L(E),$=250,O=1500,I=120;function B(e,r=I){return new Promise(t=>{let o=new N.Socket,s=!1,i=a=>{s||(s=!0,o.destroy(),t(a))};o.setTimeout(r),o.once("connect",()=>i(!0)),o.once("timeout",()=>i(!1)),o.once("error",()=>i(!1)),o.connect(e,"localhost")})}function h(e,r,t="GET",o=$,s={}){return new Promise(i=>{let a=A.request({hostname:"localhost",port:e,path:r,method:t,timeout:o,headers:s},n=>{let u="";n.on("data",l=>u+=l.toString());let c=(()=>{let l=n.headers["content-type"];if(typeof l=="string")return l;if(Array.isArray(l))return l[0]})();n.on("end",()=>i({statusCode:n.statusCode||0,body:u,contentType:c}))});a.on("error",()=>i(null)),a.setTimeout(o,()=>{a.destroy(),i(null)}),a.end()})}var H=[8081,8082,8083,8084,8085,8086,3e3,3001,19e3].map(e=>({port:e,pid:0}));function P(e,r){return!(e<=0||e>=2e4||r.has(e)||e>=5170&&e<=5200)}async function j(e=[]){let r=new Set(e);try{let{stdout:t}=await v("lsof -iTCP -sTCP:LISTEN -P -n 2>/dev/null | grep -E '^(node|bun)'",{encoding:"utf8",timeout:2e3});if(t.trim()){let o=new Map;for(let s of t.trim().split(`
3
- `)){let i=s.trim().split(/\s+/);if(i.length<9)continue;let a=Number(i[1]),u=i[8].match(/:(\d+)$/);if(!u)continue;let c=Number(u[1]);P(c,r)&&(o.has(c)||o.set(c,a))}if(o.size>0)return[...o.entries()].map(([s,i])=>({port:s,pid:i}))}}catch{}try{let{stdout:t}=await v(`ss -tlnp 2>/dev/null | grep -E '"(node|bun)"'`,{encoding:"utf8",timeout:2e3});if(t.trim()){let o=new Map;for(let s of t.trim().split(`
4
- `)){let i=s.match(/:(\d+)\s/),a=s.match(/pid=(\d+)/);if(!i)continue;let n=Number(i[1]),u=a?Number(a[1]):0;P(n,r)&&(o.has(n)||o.set(n,u))}if(o.size>0)return[...o.entries()].map(([s,i])=>({port:s,pid:i}))}}catch{}return H.filter(t=>P(t.port,r))}var y=new Map;async function W(e){if(e<=0)return null;let r=y.get(e);if(r)return r;try{let{stdout:t}=await v(`lsof -p ${e} -a -d cwd -Fn 2>/dev/null`,{encoding:"utf8",timeout:1500});for(let o of t.split(`
5
- `))if(o.startsWith("n")&&o.length>1){let s=o.slice(1).trim();if(s)return y.set(e,s),s}}catch{}return null}function F(e,r){return{port:e,framework:r,bundleUrl:p(e,`http://localhost:${e}/index.bundle?platform=ios&dev=true&hot=true&minify=false`),hmrUrl:`ws://localhost:${e}/hot`,lastSeen:Date.now()}}function p(e,r){let t=R.find(s=>s.preferredPort===e),o=t?.runtimeConfig?x(r,t.runtimeConfig):r;return k(o)}function G(e){return e.includes("/node_modules/one/metro-entry.bundle")}function z(e){try{let r=JSON.parse(e);return r&&typeof r=="object"?r:null}catch{return null}}function b(e,r,t){if(!r)return e;try{let o=JSON.parse(r.body),s=o?.extra?.expoClient||o?.extra||{};s.name&&(e.projectName=s.name),s.ios?.bundleIdentifier&&(e.bundleId=s.ios.bundleIdentifier),e.framework==="metro"&&s.sdkVersion&&(e.framework="expo");let i=o?.launchAsset?.url;i&&!e.patched&&!G(e.bundleUrl)&&(e.bundleUrl=p(e.port,i));let a=s.iconUrl||s.ios?.iconUrl||s.icon||s.ios?.icon;if(a)if(e.iconPath=a,t)if(a.startsWith("http"))e.iconUrl=t(a);else{let n=a.replace(/^\.\//,"");e.iconUrl=t(`http://localhost:${e.port}/assets/${n}`)}else e.iconUrl=a.startsWith("http")?a:`http://localhost:${e.port}/assets/${a.replace(/^\.\//,"")}`}catch{}return e}var d=new Set,f=new Set,S=new Set;async function J(e,r){if(!await B(e))return null;let t="/node_modules/one/metro-entry.bundle?platform=ios&dev=true",[o,s,i,a]=await Promise.all([d.has(e)?Promise.resolve(null):h(e,"/__soot/"),h(e,"/status"),S.has(e)?Promise.resolve(null):h(e,"/","GET",O,{"expo-platform":"ios"}),f.has(e)?Promise.resolve(null):h(e,"/_expo/status")]);a&&a.statusCode===200?f.delete(e):f.has(e)||f.add(e);let n=i?z(i.body):null,u=typeof n?.launchAsset?.url=="string"?n.launchAsset.url:null,c=n?.extra?.expoClient||n?.extra||{};if(n&&(u||typeof c.name=="string")){d.add(e);let g=u||`http://localhost:${e}/index.bundle?platform=ios&dev=true&hot=true&minify=false`,M=g.includes("/one/metro-entry.bundle")?"one":"expo";return b({port:e,framework:M,bundleUrl:p(e,g),hmrUrl:`ws://localhost:${e}/hot`,lastSeen:Date.now()},i,r)}if(s&&s.body.includes("packager-status:running"))return d.add(e),b(F(e,a&&a.statusCode===200?"expo":"metro"),i,r);if(o&&o.statusCode===200&&o.body.includes("sootsim-patched"))return d.delete(e),b({port:e,framework:"one",bundleUrl:p(e,`http://localhost:${e}/__soot/bundle.js`),hmrUrl:`ws://localhost:${e}/hot`,lastSeen:Date.now(),patched:!0},i,r);let l=await h(e,t,"HEAD");return l&&l.statusCode>0&&l.statusCode<400&&/application\/javascript/i.test(l.contentType||"")?(d.add(e),S.add(e),b({port:e,framework:"one",bundleUrl:p(e,`http://localhost:${e}${t}&minify=false`),hmrUrl:`ws://localhost:${e}/hot`,lastSeen:Date.now()},i,r)):(d.add(e),null)}function K(e){let r=e.projectName?.trim().toLowerCase();return!!(r==="soot"||r==="sootsim"||e.bundleId?.trim().toLowerCase()?.startsWith("dev.soot"))}var w=new Map,V=3e4,q=1500;function Q(e){return!e||e.framework==="metro"||e.framework==="unknown"}function Y(e){return e?p(e.port,e.bundleUrl)===e.bundleUrl:!0}function X(e,r,t=Date.now()){if(r===0||e.pid!==r||!Y(e.result))return!1;let o=t-e.cachedAt;return!(e.result===null&&o>=V||Q(e.result)&&o>=q)}async function ce(e={}){let r=await j(e.excludePorts),t=new Set(r.map(n=>n.port));for(let n of[...w.keys()])t.has(n)||w.delete(n);for(let n of[...d])t.has(n)||d.delete(n);for(let n of[...f])t.has(n)||f.delete(n);for(let n of[...S])t.has(n)||S.delete(n);let o=[],s=[];for(let{port:n,pid:u}of r){let c=w.get(n);if(c&&X(c,u)){c.result&&o.push(c.result);continue}c&&c.pid!==u&&(d.delete(n),f.delete(n),S.delete(n)),s.push({port:n,pid:u})}s.length>0&&(await Promise.all(s.map(u=>J(u.port,e.buildIconProxyUrl)))).forEach((u,c)=>{let{port:l,pid:g}=s[c];g!==0&&w.set(l,{pid:g,result:u,cachedAt:Date.now()}),u&&o.push(u)});let i=new Map;for(let{port:n,pid:u}of r)u>0&&i.set(n,u);await Promise.all(o.map(async n=>{let u=i.get(n.port);if(!u)return;n.pid=u;let c=await W(u);c&&(n.cwd=c)}));let a=new Set(i.values());for(let n of[...y.keys()])a.has(n)||y.delete(n);return o.filter(n=>!K(n))}export{x as a,ee as b,k as c,J as d,ce as e};
@@ -1,4 +0,0 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as R}from"./chunk-CTXIRBH2.js";import{n as D}from"./chunk-KLFGCFE4.js";import{a as T}from"./chunk-62DPZPFC.js";function Y(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.type=="string"&&typeof t.ts=="number"}function I(e){let t=e.trim();if(!t)return null;try{let r=JSON.parse(t);return Y(r)?r:null}catch{return null}}import{randomBytes as G,createHash as q}from"node:crypto";import m from"node:fs";import y from"node:path";var N=null;function _(){if(N)return N;let e=process.env.SOOTSIM_USER_DATA_DIR;return e||D()}function h(){return _()}function U(){return y.join(_(),"attached-projects.json")}function $(){return{version:1,attachedProjects:[],previewAttachments:[],agentSessions:[]}}function S(){let e=U(),t;try{t=m.readFileSync(e,"utf8")}catch(r){if(r.code==="ENOENT")return $();throw r}try{let r=JSON.parse(t);if(!r||typeof r!="object")throw new Error("not an object");return{version:1,attachedProjects:Array.isArray(r.attachedProjects)?r.attachedProjects:[],previewAttachments:Array.isArray(r.previewAttachments)?r.previewAttachments:[],agentSessions:Array.isArray(r.agentSessions)?r.agentSessions:[]}}catch(r){let n=`${e}.corrupt-${Date.now()}`;try{m.renameSync(e,n),console.warn(`[sootsim] attached-projects.json was unparseable; quarantined to ${n}. original error: ${r.message}`)}catch{}return $()}}function X(e){let t=U();m.mkdirSync(y.dirname(t),{recursive:!0});let r=`${t}.tmp-${process.pid}-${Date.now()}`,n=m.openSync(r,"w",384);try{m.writeFileSync(n,JSON.stringify(e,null,2)),m.fsyncSync(n)}finally{m.closeSync(n)}m.renameSync(r,t)}function w(e){let t=S();return e(t),X(t),t}function B(e){return q("sha256").update(y.resolve(e)).digest("hex").slice(0,16)}function K(){return`s_${G(10).toString("hex")}`}function ge(e){let t=y.resolve(e.cwd),r=B(t),n;return w(o=>{let s=o.attachedProjects.find(c=>c.id===r);if(s){let c={...s,...e,id:r,cwd:t,sourceRoots:e.sourceRoots??s.sourceRoots,knownBundleUrls:e.knownBundleUrls??s.knownBundleUrls,pinnedSourceResolutions:e.pinnedSourceResolutions??s.pinnedSourceResolutions,telemetry:e.telemetry??s.telemetry,updatedAt:Date.now(),createdAt:s.createdAt},g=o.attachedProjects.indexOf(s);o.attachedProjects[g]=c,n=c;return}let a=Date.now(),d={id:r,name:e.name??y.basename(t),cwd:t,repoRoot:e.repoRoot,sourceRoots:e.sourceRoots??[t],framework:e.framework??"unknown",bundleId:e.bundleId,knownBundleUrls:e.knownBundleUrls??[],preferredProvider:e.preferredProvider??"codex",preferredTransport:e.preferredTransport??"tmux",editorOpenCommand:e.editorOpenCommand,moshiWebhookToken:e.moshiWebhookToken,pinnedSourceResolutions:e.pinnedSourceResolutions??{},isolateDiscovery:e.isolateDiscovery,git:e.git,telemetry:e.telemetry??{lastOpened:0,runsCompleted:0},createdAt:a,updatedAt:a};o.attachedProjects.push(d),n=d}),n}function F(e){return S().attachedProjects.find(t=>t.id===e)??null}function ye(){return S().attachedProjects}var Q=336*60*60*1e3;function he(e,t={}){w(r=>{let n=r.attachedProjects.find(s=>s.id===e);if(!n)return;let o=t.ts??Date.now();if(n.telemetry.runsCompleted=(n.telemetry.runsCompleted??0)+1,typeof t.usd=="number"&&Number.isFinite(t.usd)&&t.usd>=0){let s=n.telemetry.costHistory??[],a=o-Q,d=s.filter(c=>c.ts>=a);d.push({ts:o,usd:t.usd}),n.telemetry.costHistory=d}n.updatedAt=o})}function Se(e,t=Date.now()){let r=t-6048e5,n=e.telemetry.costHistory??[],o=0;for(let s of n)s.ts>=r&&(o+=s.usd);return o}function we(e){w(t=>{t.attachedProjects=t.attachedProjects.filter(r=>r.id!==e),t.agentSessions=t.agentSessions.filter(r=>r.projectId!==e),t.previewAttachments=t.previewAttachments.filter(r=>r.projectId!==e)})}function M(e){let t;return w(r=>{if(e.id){let a=r.agentSessions.find(d=>d.id===e.id);if(a){let d={...a,...e,lastSeenAt:Date.now()},c=r.agentSessions.indexOf(a);r.agentSessions[c]=d,t=d;return}}let n=r.attachedProjects.find(a=>a.id===e.projectId);if(!n)throw new Error(`upsertSession: no AttachedProject with id=${e.projectId}`);let o=Date.now(),s={id:e.id??K(),projectId:e.projectId,provider:e.provider,transport:e.transport??n.preferredTransport,cwd:e.cwd??n.cwd,claudeSessionUuid:e.claudeSessionUuid,tmuxSessionName:e.tmuxSessionName,wrapperPid:e.wrapperPid,status:e.status??"idle",needsAttention:e.needsAttention??!1,lastPrompt:e.lastPrompt,lastSummary:e.lastSummary,lastTurnFiles:e.lastTurnFiles,currentlyEditing:e.currentlyEditing,lastSeenAt:o,createdAt:o};r.agentSessions.push(s),t=s}),t}function k(e){return S().agentSessions.find(t=>t.id===e)??null}function C(e){let t=S().agentSessions;return e?t.filter(r=>r.projectId===e):t}function v(e,t){w(r=>{let n=r.agentSessions.find(s=>s.id===e);if(!n)return;let o=r.agentSessions.indexOf(n);r.agentSessions[o]={...n,...t,id:n.id,projectId:n.projectId,createdAt:n.createdAt,lastSeenAt:Date.now()}})}async function ve(){if(S().attachedProjects.length>0)return;let t;try{t=(await import("./demo-app-registry-SU74KYFQ.js")).APPS}catch(n){console.warn("[sootsim] seedFromDemoAppRegistry: could not load demo registry:",n.message);return}if(!Array.isArray(t))return;let r=t;w(n=>{for(let o of r){if(!m.existsSync(o.dir))continue;let s=y.resolve(o.dir),a=B(s);if(n.attachedProjects.some(c=>c.id===a))continue;let d=Date.now();n.attachedProjects.push({id:a,name:o.label,cwd:s,sourceRoots:[s],framework:o.framework,knownBundleUrls:[`http://localhost:${o.preferredPort}/index.bundle`],preferredProvider:"codex",preferredTransport:"tmux",pinnedSourceResolutions:{},telemetry:{lastOpened:0,runsCompleted:0},createdAt:d,updatedAt:d})}})}import{spawn as V,spawnSync as z}from"node:child_process";import{randomUUID as Z}from"node:crypto";import i,{constants as f}from"node:fs";import u from"node:path";import ee from"node:readline";function j(e){return u.join(h(),"sessions",e)}function W(e){return u.join(j(e),"prompt.in")}function J(e){return u.join(j(e),"events.out")}function te(e){return u.join(h(),"transcripts",`${e}.log`)}function O(e,t){if(!e)return!1;try{process.kill(e,0)}catch{return!1}return!(t&&!i.existsSync(j(t)))}function re(){if(process.env.SOOTSIM_BIN)return{cmd:process.env.SOOTSIM_BIN,prefixArgs:[]};if(process.versions.electron){let n=process.resourcesPath;if(n){let o=[u.join(n,"bin","sootsim"),u.join(n,"bin",`sootsim-${process.platform}-${process.arch}`)];for(let s of o)if(i.existsSync(s))return{cmd:s,prefixArgs:[]}}}let e=ne();if(e)return e;let t=process.argv[0],r=process.argv[1];if(r&&/\.(ts|tsx|mjs|cjs|js)$/.test(r))return{cmd:t,prefixArgs:[r]};if(!r||r.includes("/.bin/"))throw new Error("sootsim CLI not found. set SOOTSIM_BIN to the path of the sootsim binary, or build the workspace CLI via `bun run --cwd packages/sootsim build:cli`.");return{cmd:t,prefixArgs:[]}}function ne(){try{let e=se();if(!e)return null;let t=`sootsim-${process.platform}-${process.arch}`,r=u.join(e,"dist-bin",t);if(i.existsSync(r))return{cmd:r,prefixArgs:[]};let n=u.join(e,"dist-cli","bin.js");if(i.existsSync(n)){try{let o=u.join(e,"cli","commands","agent-wrapper.ts");if(i.existsSync(o)){let s=i.statSync(o).mtimeMs;i.statSync(n).mtimeMs<s&&console.warn("[sootsim] dist-cli/bin.js is older than agent-wrapper.ts \u2014 rebuild with `bun run --cwd packages/sootsim build:cli` (watch:cli:binary builds dist-bin/ instead).")}}catch{}return{cmd:process.execPath,prefixArgs:[n]}}return null}catch{return null}}function se(){try{let r=T.resolve("sootsim/package.json");return u.dirname(r)}catch{}let e=oe();if(!e)return null;let t=u.dirname(e);for(let r=0;r<8;r++){let n=u.join(t,"package.json");try{if(i.existsSync(n)&&JSON.parse(i.readFileSync(n,"utf8")).name==="sootsim")return t}catch{}let o=u.dirname(t);if(o===t)break;t=o}return null}function oe(){try{let e=import.meta.url;return!e||!e.startsWith("file://")?null:decodeURIComponent(e.slice(7))}catch{return null}}async function ie(e,t,r){let n=u.join(h(),"locks");i.mkdirSync(n,{recursive:!0});try{i.chmodSync(n,448)}catch{}let o=u.join(n,`start-${e}-${t}.lock`),s=Date.now()+4e3,a=null;for(;a===null;)try{a=i.openSync(o,f.O_WRONLY|f.O_CREAT|f.O_EXCL,384)}catch(d){if(d.code!=="EEXIST")throw d;try{let c=Number(i.readFileSync(o,"utf8").trim());if(c&&!ce(c)){i.unlinkSync(o);continue}}catch{}if(Date.now()>s)throw new Error(`another start is in progress for project=${e} provider=${t} (lock: ${o})`);await new Promise(c=>setTimeout(c,50))}try{return i.writeFileSync(a,String(process.pid)),await r()}finally{try{i.closeSync(a)}catch{}try{i.unlinkSync(o)}catch{}}}function ce(e){try{return process.kill(e,0),!0}catch{return!1}}function L(e){let t=u.dirname(e);i.mkdirSync(t,{recursive:!0});try{i.chmodSync(t,448)}catch{}if(i.existsSync(e))try{if(i.statSync(e).isFIFO()){try{i.chmodSync(e,384)}catch{}return}i.unlinkSync(e)}catch{i.unlinkSync(e)}let r=z("mkfifo",["-m","600",e]);if(r.status!==0)throw new Error(`mkfifo(${e}) failed: ${r.stderr?.toString().trim()||"unknown error"}`)}var l=class extends Error{code;constructor(t,r){super(r),this.code=t}};async function Te(e){let t=F(e.projectId);if(!t)throw new l("NO_PROJECT",`no project with id=${e.projectId}`);let r=e.provider||t.preferredProvider||"codex";return ie(t.id,r,async()=>{let n=C(t.id).find(p=>p.provider===r&&p.status!=="ended"&&O(p.wrapperPid,p.id));if(n)throw new l("ALREADY_RUNNING",`session already running for project=${t.id} provider=${r} (session ${n.id}, pid ${n.wrapperPid}). end it first with \`sootsim agent end <sessionId>\`.`);let o=r==="claude"?Z():void 0,s=M({projectId:t.id,provider:r,transport:"pty",cwd:t.cwd,status:"idle",claudeSessionUuid:o}),a=W(s.id),d=J(s.id),c=te(s.id);L(a),L(d);let g=u.dirname(c);i.mkdirSync(g,{recursive:!0});try{i.chmodSync(g,448)}catch{}let{cmd:A,prefixArgs:H}=re(),P=[...H,"agent-wrapper","--session-id",s.id,"--project-id",t.id,"--provider",r,"--cwd",t.cwd,"--prompt-in",a,"--events-out",d,"--transcript",c];e.codexBin&&P.push("--codex-bin",e.codexBin),e.claudeBin&&P.push("--claude-bin",e.claudeBin),e.freshThread&&P.push("--fresh-thread"),o&&P.push("--claude-session-uuid",o);let x=V(A,P,{detached:!0,stdio:"ignore",env:{...process.env,SOOTSIM_USER_DATA_DIR:h()}});x.unref();let E=e.readyTimeoutMs??6e3,b=await ae(d,p=>p.type==="ready"||p.type==="error",E);if(!b||b.type==="error"){if(x.pid)try{process.kill(x.pid,"SIGTERM")}catch{}try{i.rmSync(j(s.id),{recursive:!0,force:!0})}catch{}v(s.id,{status:"ended"});let p=b&&b.type==="error"?b.message:`no ready event within ${E}ms`;throw new l("WRAPPER_FAILED",p)}return v(s.id,{wrapperPid:x.pid,status:"idle"}),{session:k(s.id),wrapperPid:x.pid}})}async function De(e,t){let r=k(e);if(!r)throw new l("NO_SESSION",`no session with id=${e}`);if(!O(r.wrapperPid,e))throw v(e,{status:"ended"}),new l("NOT_ALIVE",`session wrapper is not alive (pid=${r.wrapperPid}). start a new session.`);let n=W(e);if(!i.existsSync(n))throw new l("NO_FIFO",`prompt FIFO missing: ${n}`);let o=i.openSync(n,f.O_WRONLY);try{let s=R(t);if(!s)throw new l("EMPTY_PROMPT","prompt text is empty");i.writeSync(o,s+`
3
- `)}finally{i.closeSync(o)}v(e,{lastPrompt:t.displayText??t.text,status:"working"})}async function Re(e){let t=k(e);if(!t)throw new l("NO_SESSION",`no session with id=${e}`);if(O(t.wrapperPid,e))try{process.kill(t.wrapperPid,"SIGTERM")}catch{}let r=j(e),n=h();if(r.startsWith(n))try{i.rmSync(r,{recursive:!0,force:!0})}catch{}v(e,{status:"ended",wrapperPid:void 0})}function Ne(e,t){let r=J(e);if(!i.existsSync(r))throw new l("NO_FIFO",`events FIFO missing: ${r}`);let n=i.openSync(r,f.O_RDWR),o=i.createReadStream("",{fd:n,autoClose:!0}),s=ee.createInterface({input:o,crlfDelay:1/0});s.on("line",d=>{let c=I(d);c&&t(c)});let a=!1;return()=>{if(!a){a=!0;try{s.close()}catch{}try{o.destroy()}catch{}}}}async function ae(e,t,r){let n=i.openSync(e,f.O_RDWR|f.O_NONBLOCK),o=Buffer.alloc(8192),s="",a=Date.now()+r;try{for(;Date.now()<a;){let d=0;try{d=i.readSync(n,o,0,o.length,null)}catch(c){if(c.code!=="EAGAIN")throw c;d=0}if(d>0){s+=o.subarray(0,d).toString("utf8");let c;for(;(c=s.indexOf(`
4
- `))>=0;){let g=s.slice(0,c);s=s.slice(c+1);let A=I(g);if(A&&t(A))return A}}else await new Promise(c=>setTimeout(c,30))}return null}finally{i.closeSync(n)}}export{I as a,h as b,ge as c,F as d,ye as e,he as f,Se as g,we as h,k as i,C as j,v as k,ve as l,j as m,W as n,J as o,te as p,O as q,re as r,l as s,Te as t,De as u,Re as v,Ne as w};
@@ -1 +0,0 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -1,64 +0,0 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as v}from"./chunk-62DPZPFC.js";import{existsSync as o,readFileSync as p,writeFileSync as d}from"node:fs";import{homedir as H}from"node:os";import{dirname as $,join as s,resolve as P}from"node:path";var _=H();function X(e){let t=e;for(;;){if(o(s(t,"pnpm-workspace.yaml"))||o(s(t,"turbo.json"))||o(s(t,"nx.json"))||o(s(t,"lerna.json")))return t;let r=s(t,"package.json");if(o(r))try{if(JSON.parse(p(r,"utf8")).workspaces)return t}catch{}let n=$(t);if(n===t)return null;t=n}}function A(e,t){let r=X(process.cwd()),n=[r?P(r,e):null,P(process.cwd(),e),P(process.cwd(),t)].filter(a=>!!a);for(let a of n)if(o(a))return a;return n[0]??P(process.cwd(),e)}var Q=()=>A("packages/sootsim-engine/scripts/expensify-web-proxy.ts","scripts/expensify-web-proxy.ts"),Z=()=>A("packages/sootsim-engine/scripts/rainbow-metadata-proxy.ts","scripts/rainbow-metadata-proxy.ts"),z=()=>A("packages/compat/src/stubs/mattermost-rnutils-native.ts","../compat/src/stubs/mattermost-rnutils-native.ts"),ee=()=>A("packages/compat/src/stubs/native-seams/react-native-keychain-manager.ts","../compat/src/stubs/native-seams/react-native-keychain-manager.ts"),L=()=>A("packages/compat/src/stubs/mattermost-network-client-native.ts","../compat/src/stubs/mattermost-network-client-native.ts"),te=()=>A("packages/sootsim-engine/scripts/mattermost-preview-server.ts","scripts/mattermost-preview-server.ts"),D={USE_NGROK:"true",NGROK_URL:"http://localhost:9000/",SECURE_NGROK_URL:"http://localhost:9000/"},ne=s(_,"github/mattermost-mobile"),I=s(_,"github/uniswap-interface"),re=s(I,"apps/mobile"),T=s(I,".env.defaults.local"),se="stored-in-.env.local",M="# sootsim demo env overrides",oe=s(I,"packages/uniswap/src/features/forceUpgrade/hooks/useForceUpgradeStatus.ts"),ae=s(I,"apps/mobile/src/notification-service/data-sources/createForceUpgradeNotificationDataSource.ts"),W="SOOTSIM_DEMO_DISABLE_FORCE_UPGRADE";function B(e){if(!o(e))return{};let t={},r=p(e,"utf8");for(let n of r.split(/\r?\n/)){let a=n.trim();if(!a||a.startsWith("#"))continue;let u=a.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!u)continue;let i=u[2].trim();(i.startsWith('"')&&i.endsWith('"')||i.startsWith("'")&&i.endsWith("'"))&&(i=i.slice(1,-1)),t[u[1]]=i}return t}function k(e){if(!e)return!1;let t=e.trim();return!(!t||t.includes(se)||t==="TRADING_API_KEY"||t==="UNISWAP_API_KEY")}function Y(e,t){for(let r of e)for(let n of t){let a=r[n];if(k(a))return a.trim()}}function V(){let e=B(T),t=B(s(I,"apps/web/.env")),r=[process.env,e,t],n={},a=[["AMPLITUDE_PROXY_URL_OVERRIDE",["REACT_APP_AMPLITUDE_PROXY_URL"]],["QUICKNODE_ENDPOINT_NAME",["REACT_APP_QUICKNODE_ENDPOINT_NAME"]],["QUICKNODE_ENDPOINT_TOKEN",["REACT_APP_QUICKNODE_ENDPOINT_TOKEN"]],["INFURA_KEY",["REACT_APP_INFURA_KEY"]],["STATSIG_API_KEY",["REACT_APP_STATSIG_API_KEY"]],["STATSIG_PROXY_URL_OVERRIDE",["REACT_APP_STATSIG_PROXY_URL"]],["WALLETCONNECT_PROJECT_ID",["REACT_APP_WALLET_CONNECT_PROJECT_ID"]],["WALLETCONNECT_PROJECT_ID_BETA",["REACT_APP_WALLET_CONNECT_PROJECT_ID"]],["WALLETCONNECT_PROJECT_ID_DEV",["REACT_APP_WALLET_CONNECT_PROJECT_ID"]],["TRADING_API_KEY",["REACT_APP_TRADING_API_KEY"]],["UNISWAP_API_KEY",[]]];for(let[i,E]of a){let l=Y(r,[i,...E]);if(l){n[i]=l;for(let f of E)n[f]=l}}if(!(k(n.TRADING_API_KEY)&&k(n.UNISWAP_API_KEY))){let i=Y(r,["GRAPHQL_URL_OVERRIDE","REACT_APP_AWS_API_ENDPOINT"])||"https://interface.gateway.uniswap.org/v1/graphql";n.API_BASE_URL_OVERRIDE="https://interface.gateway.uniswap.org",n.API_BASE_URL_V2_OVERRIDE="https://interface.gateway.uniswap.org/v2",n.GRAPHQL_URL_OVERRIDE=i,n.TRADING_API_URL_OVERRIDE="https://trading-api-labs.interface.gateway.uniswap.org",n.FOR_API_URL_OVERRIDE="https://for.interface.gateway.uniswap.org/v2/FOR.v1.FORService"}return n}function ie(){let e=o(T)?p(T,"utf8"):"";if(e&&!e.includes(M))return;let t=V(),r=[M];for(let[n,a]of Object.entries(t).sort(([u],[i])=>u.localeCompare(i)))r.push(`${n}=${JSON.stringify(a)}`);r.push(""),d(T,`${r.join(`
3
- `)}
4
- `)}function ce(){let e=`export function useForceUpgradeStatus(): ForceUpgradeStatus {
5
- `,t=` // sootsim demo: bypass the force-upgrade gate during local engine demos.
6
- return 'not-required'
7
-
8
- `,r=` // sootsim demo: bypass the force-upgrade gate during local engine demos.
9
- if (process.env.${W} === 'true') {
10
- return 'not-required'
11
- }
12
-
13
- `,n=` const getForceUpgradeStatus = (): ForceUpgradeStatus => {
14
- `,a=` // sootsim demo: bypass the force-upgrade gate during local engine demos.
15
- return 'not-required'
16
-
17
- `,u=` // sootsim demo: bypass the force-upgrade gate during local engine demos.
18
- if (process.env.${W} === 'true') {
19
- return 'not-required'
20
- }
21
-
22
- `,i=(E,l,f,U)=>{let g=p(E,"utf8");if(!g.includes(f)){if(g.includes(U)){d(E,g.replace(U,f));return}if(!g.includes(l))throw new Error(`uniswap demo patch failed: expected snippet not found in ${E}`);d(E,g.replace(l,`${l}${f}`))}};i(oe,e,t,r),i(ae,n,a,u)}var R=s(_,"github/joplin"),_e=s(R,"packages/app-mobile"),de=["packages/lib","packages/renderer","packages/turndown","packages/turndown-plugin-gfm","packages/editor","packages/tools","packages/utils","packages/fork-htmlparser2","packages/fork-uslug","packages/fork-sax","packages/htmlpack","packages/react-native-saf-x","packages/react-native-alarm-notification"];function pe(){if(o(R))for(let e of de){let t=s(R,e);if(!o(t))continue;let r=s(t,".watchmanconfig");o(r)||d(r,`{}
23
- `)}}var x=["packages/lib/models/Setting.js","packages/turndown/lib/turndown.cjs.js","packages/app-mobile/pluginAssets/index.js"];function ue(){if(!o(R)||x.filter(n=>!o(s(R,n))).length===0)return;let{execSync:t}=v("node:child_process");t("yarn buildParallel",{cwd:R,stdio:"inherit",env:{...process.env,NO_FLIPPER:"1",CI:""}});let r=x.filter(n=>!o(s(R,n)));if(r.length>0)throw new Error(`joplin demo: yarn buildParallel did not produce: ${r.join(", ")}`)}var m=s(_,"github/rainbow"),O=s(m,"src/graphql"),y=s(O,"config.js"),N=s(m,"src/references/networks.json"),S="https://metadata.p.rainbow.me",w=9011,C=`http://127.0.0.1:${w}`,K="https://api.thegraph.com/subgraphs/name/ensdomains/ens",J="0x0000000000000000000000000000000000000000",Ee="https://relay.rainbow.me",le="sootsim-rainbow-demo-master-key-do-not-use-for-real-wallets",Re="https://rpc.rainbow.me/v1",me="",j={1:"https://ethereum-rpc.publicnode.com"},G="sootsim-rainbow-demo-api-key",Ae="0x736f6f7473696d2d7261696e626f772d64656d6f2d686173682d6b6579000000",fe="00000000000000000000000000000000",ge=["src/graphql/__generated__/ens.ts","src/graphql/__generated__/metadata.ts","src/graphql/__generated__/metadataPOST.ts"];function b(e,t){let{execSync:r}=v("node:child_process");r(e,{cwd:t,stdio:"inherit",env:{...process.env,METADATA_BASE_URL:S,RAINBOW_RELAY_QUOTE_SIGNER:process.env.RAINBOW_RELAY_QUOTE_SIGNER??J}})}function Oe(){if(!o(O))return;let e=o(y)?p(y,"utf8"):"";e.includes(K)&&e.includes(S)||d(y,`exports.config = {
24
- ens: {
25
- __name: 'ens',
26
- document: './queries/ens.graphql',
27
- schema: {
28
- method: 'POST',
29
- url: '${K}',
30
- },
31
- },
32
- metadata: {
33
- __name: 'metadata',
34
- document: './queries/metadata.graphql',
35
- schema: { method: 'GET', url: '${S}/v1/graph' },
36
- },
37
- metadataPOST: {
38
- __name: 'metadataPOST',
39
- document: './queries/metadata.graphql',
40
- schema: { method: 'POST', url: '${S}/v1/graph' },
41
- },
42
- arc: {
43
- __name: 'arc',
44
- document: './queries/arc.graphql',
45
- schema: {
46
- method: 'GET',
47
- url: 'https://arc-graphql.rainbow.me/graphql',
48
- headers: {
49
- 'x-api-key': 'ARC_GRAPHQL_API_KEY',
50
- },
51
- },
52
- },
53
- arcDev: {
54
- __name: 'arcDev',
55
- document: './queries/arc.graphql',
56
- schema: {
57
- method: 'GET',
58
- url: 'https://arc-graphql.rainbowdotme.workers.dev/graphql',
59
- headers: {},
60
- },
61
- },
62
- };
63
- `)}function Se(){let e={ENABLE_DEV_MODE:"1",IS_TESTING:"false",METADATA_BASE_URL:process.env.RAINBOW_METADATA_BASE_URL??C,ADDYS_API_KEY:process.env.ADDYS_API_KEY??G,ADDYS_BASE_URL:process.env.ADDYS_BASE_URL??C,PLATFORM_API_KEY:process.env.PLATFORM_API_KEY??G,PLATFORM_BASE_URL:process.env.PLATFORM_BASE_URL??C,RAINBOW_MASTER_KEY:process.env.RAINBOW_MASTER_KEY??le,RAINBOW_RELAY_QUOTE_SIGNER:process.env.RAINBOW_RELAY_QUOTE_SIGNER??J,RAINBOW_RELAY_URL:process.env.RAINBOW_RELAY_URL??Ee,RPC_PROXY_API_KEY_PROD:me,RPC_PROXY_BASE_URL_PROD:process.env.RAINBOW_RPC_PROXY_BASE_URL??process.env.RPC_PROXY_BASE_URL_PROD??Re,SECURE_WALLET_HASH_KEY:process.env.SECURE_WALLET_HASH_KEY??Ae,WC_PROJECT_ID:process.env.WC_PROJECT_ID??process.env.RAINBOW_WALLETCONNECT_PROJECT_ID??fe},t=["ADDYS_API_KEY","ADDYS_BASE_URL","IMGIX_DOMAIN","IMGIX_TOKEN","PLATFORM_API_KEY","PLATFORM_BASE_URL","RAINBOW_TEST_WALLET","RAINBOW_RELAY_API_KEY","RAINBOW_RELAY_URL","SECURE_WALLET_HASH_KEY","TOKEN_SEARCH_URL"];for(let r of t){let n=process.env[r];n&&(e[r]=n)}return e}function Ie(){if(!o(N))return;let e=JSON.parse(p(N,"utf8"));if(!Array.isArray(e.networks))return;let t=!1;for(let r of e.networks){let n=r.id?j[r.id]:void 0;!n||!r.defaultRPC||r.defaultRPC.url!==n&&(r.defaultRPC.url=n,t=!0)}t&&d(N,`${JSON.stringify(e)}
64
- `)}function Pe(){if(!o(m))return;Oe(),o(s(O,"node_modules/.bin/graphql-codegen"))||b("fnm exec --using=22 yarn install",O),ge.some(t=>!o(s(m,t)))&&b("fnm exec --using=22 yarn codegen",O),o(N)||b("fnm exec --using=22 yarn fetch:networks",m),Ie()}var c=s(_,"github/eigen"),h=s(c,"keys.shared.json"),F=s(c,"metaflags.json"),q=s(c,"src/__generated__/.relay-complete");function Te(){if(o(h))try{let e=JSON.parse(p(h,"utf8"));if(!e||typeof e!="object")return;let t=e.secure&&typeof e.secure=="object"?e.secure:void 0,r=e.public&&typeof e.public=="object"?e.public:void 0;return!t&&!r?void 0:{secure:t,public:r}}catch{return}}function Ne(){let e=process.env.SOOTSIM_ARTSY_EMAIL??process.env.MAESTRO_TEST_EMAIL,t=process.env.SOOTSIM_ARTSY_PASSWORD??process.env.MAESTRO_TEST_PASSWORD,r=Te(),n={};if(e&&t&&(n.SOOTSIM_LAUNCH_ARGUMENTS=JSON.stringify({email:e,password:t,useMaestroInit:!0})),r&&(n.SOOTSIM_REACT_NATIVE_KEYS_JSON=JSON.stringify(r)),Object.keys(n).length!==0)return{env:n}}function he(){if(!o(c))return;let{execSync:e}=v("node:child_process"),t=s(c,".yarn/releases/yarn-4.10.3.cjs");if(o(t)){let n=p(t,"utf8"),a='["clone","-c core.autocrlf=false",';n.includes(a)&&d(t,n.replace(a,'["clone","-c","core.autocrlf=false",'))}if(o(s(c,"node_modules/.yarn-state.yml"))||e("yarn install",{cwd:c,stdio:"inherit",env:{...process.env,YARN_CHECKSUM_BEHAVIOR:"update"}}),!o(h)||!o(F))try{e("yarn setup:oss",{cwd:c,stdio:"inherit"})}catch{if(!o(h)||!o(F))throw new Error("artsy demo: setup:oss did not create keys/metaflags")}let r=s(c,"node_modules/react-native-launch-arguments/package.json");if(o(r)){let n=p(r,"utf8");n.includes('"dist/index.js"')&&d(r,n.replace('"dist/index.js"','"src/index.ts"'))}o(q)||(e("yarn relay",{cwd:c,stdio:"inherit"}),d(q,""))}var ye=[{name:"bluesky",label:"Bluesky",dir:s(_,"github/bluesky"),preferredPort:8082,framework:"expo",command:e=>({cmd:`npx expo start --port ${e}`}),credentials:{envVars:["SOOTSIM_BLUESKY_PASSWORD"],known:{HANDLE:"natew.bsky.social"}}},{name:"3pc",label:"3PunchConvo",dir:s(_,"lightstrike-labs/three-punch-convo-app/apps/one"),preferredPort:8081,framework:"one",command:e=>({cmd:"npx one dev",env:{ONE_PORT:String(e)}})},{name:"uniswap",label:"Uniswap",dir:re,preferredPort:8085,framework:"expo",prepare:()=>{ie(),ce()},command:e=>({cmd:`npx expo start --clear --port ${e}`,env:V()})},{name:"takeout",label:"Takeout",dir:s(_,"takeout"),preferredPort:8086,framework:"one",readyTimeoutMs:24e4,managedPorts:e=>{let t=e-8081;return[5433+t,4848+t,9200+t]},command:e=>({cmd:"bun lite:demo",env:{TAKEOUT_ENV_MODE:"development",PORT_OFFSET:String(e-8081),OREZ_DATA_DIR:`${_}/.cache/sootsim-demo/takeout-orez`,VITE_DEMO_MODE:"1",ZERO_APP_ID:"takeout",ZERO_APP_PUBLICATIONS:"zero_takeout",ZERO_CVR_MAX_CONNS:"4",ZERO_NUM_SYNC_WORKERS:"2",ZERO_UPSTREAM_MAX_CONNS:"8"}})},{name:"expensify",label:"Expensify",dir:s(_,"github/expensify"),preferredPort:8087,framework:"rock",runtimeConfig:{env:D},sidecars:[{name:"web-proxy",port:9e3,readyPath:"/api/Ping",command:()=>({cmd:`bun ${JSON.stringify(Q())}`,env:D})}],command:e=>({cmd:`fnm exec --using=20.20.0 npx rock start --port ${e} --no-interactive`,env:D})},{name:"artsy",label:"Artsy",dir:c,preferredPort:8088,framework:"expo",runtimeConfig:Ne(),prepare:()=>{he()},command:e=>({cmd:`npx react-native start --port ${e}`}),credentials:{envVars:["SOOTSIM_ARTSY_EMAIL","SOOTSIM_ARTSY_PASSWORD"],note:"auto-login reuses Artsy\u2019s built-in Maestro launch-arguments hook"}},{name:"rainbow",label:"Rainbow",dir:m,preferredPort:8089,framework:"rock",sidecars:[{name:"metadata-proxy",port:w,readyPath:"/health",command:()=>({cmd:`bun ${JSON.stringify(Z())}`,env:{PORT:String(w),RAINBOW_PUBLIC_RPC_URLS:JSON.stringify(j),RAINBOW_UPSTREAM_METADATA_BASE_URL:S}})}],prepare:()=>{Pe()},command:e=>({cmd:`fnm exec --using=22 yarn start --port ${e} --reset-cache`,env:Se()}),credentials:{envVars:["RAINBOW_TEST_WALLET"],optionalEnvVars:["RAINBOW_WALLETCONNECT_PROJECT_ID","WC_PROJECT_ID","IMGIX_DOMAIN","IMGIX_TOKEN"],note:"launcher supplies demo encryption, public mainnet RPC, and a placeholder WalletConnect project id; use only a public throwaway mnemonic for RAINBOW_TEST_WALLET"}},{name:"rocket-chat",label:"Rocket.Chat",dir:s(_,"github/Rocket.Chat.ReactNative"),preferredPort:8093,framework:"expo",command:e=>({cmd:`npx react-native start --port ${e}`,env:{RUNNING_E2E_TESTS:"true"}}),credentials:{envVars:["ROCKET_CHAT_DEMO_SERVER","ROCKET_CHAT_DEMO_USERNAME","ROCKET_CHAT_DEMO_PASSWORD"],known:{SERVER:"https://mobile.qa.rocket.chat"},note:"use packages/sootsim-engine/scripts/rocket-chat-demo-auth.ts to create/login a disposable QA user and print the rocketchat://auth deep link"}},{name:"mattermost",label:"Mattermost",dir:ne,preferredPort:8090,framework:"expo",sidecars:[{name:"preview-server",port:8065,readyPath:"/api/v4/system/ping",command:()=>({cmd:`bun ${JSON.stringify(te())}`})}],runtimeConfig:{modules:{"react-native-keychain":!1,"dist/assets/config.json":{inline:{AuthUrlScheme:"mmauth://",AuthUrlSchemeDev:"mmauthbeta://",DefaultServerUrl:"http://localhost:8065",DefaultServerName:"Mattermost Demo",TestServerUrl:"http://localhost:8065",AutoSelectServerUrl:!0,WebsiteURL:"https://mattermost.com",ServerNoticeURL:"https://github.com/mattermost/mattermost-server/blob/master/NOTICE.txt",MobileNoticeURL:"https://github.com/mattermost/mattermost-mobile/blob/master/NOTICE.txt",RudderApiKey:"",SentryEnabled:!1,SentryDsnIos:"",SentryDsnAndroid:"",SentryOptions:{deactivateStacktraceMerging:!0,autoBreadcrumbs:{xhr:!1,console:!0},severityLevelFilter:["fatal"]},ShowReview:!1,ShowOnboarding:!1,ExperimentalNormalizeMarkdownLinks:!1,CustomRequestHeaders:{},CollectNetworkMetrics:!1}}},nativeModules:{RNKeychainManager:{file:ee()},RNUtils:{file:z()},GenericClient:{file:L()},ApiClient:{file:L()},WebSocketClient:{file:L()}}},command:e=>({cmd:`npx react-native start --host 127.0.0.1 --port ${e}`}),credentials:{known:{SERVER:"http://localhost:8065",USERNAME:"demo",PASSWORD:"DemoPassword1!"},note:"local mattermost-preview seeded through the real REST API; no signup or OTP needed"}},{name:"joplin",label:"Joplin",dir:_e,preferredPort:8084,framework:"expo",prepare:()=>{pe(),ue()},command:e=>({cmd:`npx expo start --port ${e}`,env:{BROWSERSLIST_IGNORE_OLD_DATA:"true"}}),credentials:{note:"no login required \u2014 sync.target=0 (None), seed via WelcomeUtils"}}];export{ye as a};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- var t="http://localhost:5173/";export{t as a};
@@ -1,62 +0,0 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as P,b as v}from"./chunk-WHIZNJLR.js";import{d as j}from"./chunk-3XBLSPSH.js";import{a as b}from"./chunk-KJOBH5CA.js";import{execSync as A}from"child_process";import{existsSync as w,readFileSync as _,writeFileSync as x}from"fs";import{relative as B,resolve as d}from"path";import{existsSync as p,readFileSync as k,readdirSync as O,statSync as R}from"fs";import{basename as L,dirname as T,join as a}from"path";function D(e){let o=e;for(;;){if(p(a(o,"turbo.json"))||p(a(o,"nx.json"))||p(a(o,"lerna.json"))||p(a(o,"pnpm-workspace.yaml")))return o;let i=a(o,"package.json");if(p(i))try{if(JSON.parse(k(i,"utf8")).workspaces)return o}catch{}let r=T(o);if(r===o)break;o=r}return e}function W(e){return p(a(e,"bun.lock"))||p(a(e,"bun.lockb"))?"bun":p(a(e,"pnpm-lock.yaml"))?"pnpm":p(a(e,"yarn.lock"))?"yarn":"npm"}function J(e){if(p(a(e,"turbo.json")))return"turbo";if(p(a(e,"nx.json")))return"nx";if(p(a(e,"pnpm-workspace.yaml")))return"pnpm";let o=a(e,"package.json");if(p(o))try{if(JSON.parse(k(o,"utf8")).workspaces)return"npm-workspaces"}catch{}return"single"}function N(e){return e.one?"one":e.expo?"expo":e["react-native"]?"bare":"unknown"}function y(e){let o=a(e,"package.json");if(!p(o))return null;let i;try{i=JSON.parse(k(o,"utf8"))}catch{return null}let r={...i.dependencies,...i.devDependencies},s=N(r);return s==="unknown"?null:{dir:e,name:i.name||L(e),framework:s,hasViteConfig:p(a(e,"vite.config.ts"))||p(a(e,"vite.config.js")),hasMetroConfig:p(a(e,"metro.config.js"))||p(a(e,"metro.config.ts")),hasSootsimDependency:!!r.sootsim,devCommand:i.scripts?.dev||null}}function V(e){let o=[],i=a(e,"pnpm-workspace.yaml");if(p(i)){let t=k(i,"utf8").match(/packages:\s*\n((?:\s+-\s+.+\n?)+)/);if(t){let c=t[1].split(`
3
- `).filter(Boolean);for(let n of c){let g=n.replace(/^\s*-\s*['"]?/,"").replace(/['"]?\s*$/,"");g&&o.push(...S(e,g))}}return o}let r=a(e,"package.json");if(p(r))try{let s=JSON.parse(k(r,"utf8")),t=Array.isArray(s.workspaces)?s.workspaces:s.workspaces?.packages||[];for(let c of t)o.push(...S(e,c))}catch{}return o}function S(e,o){let i=o.replace(/\/\*\*?$/,"").replace(/\*$/,""),r=a(e,i);if(!p(r))return[];try{return O(r).map(t=>a(r,t)).filter(t=>{try{return R(t).isDirectory()&&p(a(t,"package.json"))}catch{return!1}})}catch{return[]}}function M(e){let o=J(e),i=W(e);if(o==="single"){let c=y(e);return{root:e,type:o,packageManager:i,apps:c?[c]:[]}}let r=V(e),s=[],t=y(e);t&&s.push(t);for(let c of r){if(c===e)continue;let n=y(c);n&&s.push(n)}return{root:e,type:o,packageManager:i,apps:s}}function $(e){switch(e){case"bun":return"bun add -d sootsim";case"pnpm":return"pnpm add -D sootsim";case"yarn":return"yarn add -D sootsim";case"npm":return"npm install -D sootsim"}}async function ce(e){(e.includes("--help")||e.includes("-h"))&&(console.log(`
4
- sootsim setup-repo \u2014 set up sootsim in your project
5
-
6
- detects your bundler (one, expo, metro), adds sootsim as a
7
- dependency, configures the bundler plugin, and adds dev scripts.
8
-
9
- usage:
10
- sootsim setup-repo interactive setup (current directory)
11
- sootsim setup-repo --app <dir> set up the project at <dir> (default: cwd)
12
- sootsim setup-repo --yes skip confirmations
13
- sootsim setup-repo --dry-run show what would be done
14
-
15
- works with monorepos (turbo, pnpm, nx) \u2014 scans for app packages.
16
- `),process.exit(0));let o=e.includes("--yes")||e.includes("-y"),i=e.includes("--dry-run"),r=e.indexOf("--app"),s=r!==-1&&e[r+1]?d(e[r+1]):process.cwd();w(s)||(console.error(` directory not found: ${s}`),process.exit(1));let t=D(s),c=M(t);if(console.log(`
17
- sootsim \u2014 project setup
18
- `),!i)try{await j()}catch(l){console.error(` bootstrap failed: ${l instanceof Error?l.message:String(l)}`),console.error(" continuing with project setup; rerun later if needed.")}c.apps.length===0&&(console.log(" no react native apps found in this project."),console.log(` sootsim works with one, expo, and react-native projects.
19
- `),process.exit(1));let n;if(c.type!=="single"&&c.apps.length>1){console.log(` monorepo detected (${c.type} + ${c.packageManager})
20
- `);let l=await v("which app?",c.apps.map(u=>`${(B(t,u.dir)||".").padEnd(30)} (${u.framework})`));n=c.apps[l]}else n=c.apps[0];let g=n.framework==="one"?"metro (via one)":n.framework==="expo"?"metro (via expo)":"metro";console.log(" detected:"),console.log(` framework: ${n.framework}`),console.log(` bundler: ${g}`),console.log(` package: ${n.name}`),console.log(` manager: ${c.packageManager}`),console.log();let f=[];if(!n.hasSootsimDependency){let l=$(c.packageManager);f.push({label:"add sootsim as devDependency",run:()=>{A(l,{cwd:n.dir,stdio:"pipe"})}})}n.framework==="one"&&n.hasViteConfig?f.push({label:"add sootsimPlugin() to vite.config.ts",run:()=>C(n.dir)}):(n.framework==="expo"||n.framework==="bare")&&n.hasMetroConfig?f.push({label:"add withSootsim() to metro.config.js",run:()=>G(n.dir)}):n.framework==="one"?f.push({label:"add sootsimPlugin() to vite.config.ts",run:()=>C(n.dir)}):f.push({label:"create metro.config.js with withSootsim()",run:()=>z(n.dir,n.framework)}),console.log(" will:"),f.forEach((l,u)=>console.log(` ${u+1}. ${l.label}`)),console.log(),i&&(console.log(` (dry run \u2014 no changes made)
21
- `),process.exit(0)),o||(await P("continue?")||(console.log(`
22
- cancelled.
23
- `),process.exit(0)),console.log());let h=0;for(let l=0;l<f.length;l++){let u=f[l];process.stdout.write(` [${l+1}/${f.length}] ${u.label}...`);try{u.run(),console.log(" done")}catch(m){h++,console.log(` failed: ${m.message}`),(u.label.includes("vite.config")||u.label.includes("metro.config"))&&H(n)}}b({event:"cli_setup_repo",properties:{framework:n.framework,package_manager:c.packageManager,workspace_type:c.type,step_count:f.length,step_failures:h}}),console.log(`
24
- done! run your app normally and hit:
25
-
26
- then open:
27
- http://localhost:8081/__soot/
28
- `)}function C(e){let o=d(e,"vite.config.ts")||d(e,"vite.config.js"),i=d(e,"vite.config.ts"),r=d(e,"vite.config.js"),s=w(i)?i:r;if(!w(s))throw new Error(`no vite config found at ${e}`);let t=_(s,"utf8");if(t.includes("sootsimPlugin")){console.log(" (already configured)");return}let c="import { sootsimPlugin } from 'sootsim/vite'",n=/^(import\s+.+)$/gm,g=0,f;for(;(f=n.exec(t))!==null;)g=f.index+f[0].length;g>0?t=t.slice(0,g)+`
29
- `+c+t.slice(g):t=c+`
30
- `+t;let h=t.match(/plugins\s*:\s*\[/);if(h&&h.index!==void 0){let l=h.index+h[0].length,u=1,m=l;for(;m<t.length&&u>0;)t[m]==="["&&u++,t[m]==="]"&&u--,u>0&&m++;let E=t.slice(0,m),q=t.slice(m),F=t.slice(l).match(/\n(\s+)\S/)?.[1]||" ",I=t.slice(t.lastIndexOf(`
31
- `,m),m+1).match(/\n(\s*)/)?.[1]||" ";t=E.trimEnd()+`
32
- `+F+`sootsimPlugin(),
33
- `+I+q}else throw new Error("could not find plugins array in vite config");x(s,t)}function G(e){let o=d(e,"metro.config.js"),i=d(e,"metro.config.ts"),r=w(o)?o:i;if(!w(r))throw new Error(`no metro config found at ${e}`);let s=_(r,"utf8");if(s.includes("withSootsim")){console.log(" (already configured)");return}s="const { withSootsim } = require('sootsim/metro')"+`
34
- `+s,s=s.replace(/(module\.exports\s*=\s*)([^;]+)/,(c,n,g)=>`${n}withSootsim(${g.trim()})`),x(r,s)}function z(e,o){let i=d(e,"metro.config.js"),r;o==="expo"?r=`const { getDefaultConfig } = require('expo/metro-config')
35
- const { withSootsim } = require('sootsim/metro')
36
-
37
- const config = getDefaultConfig(__dirname)
38
-
39
- module.exports = withSootsim(config)
40
- `:r=`const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')
41
- const { withSootsim } = require('sootsim/metro')
42
-
43
- const config = {}
44
-
45
- module.exports = withSootsim(mergeConfig(getDefaultConfig(__dirname), config))
46
- `,x(i,r)}function H(e){e.framework==="one"?console.log(`
47
- manual setup \u2014 add to your vite.config.ts:
48
-
49
- import { sootsimPlugin } from 'sootsim/vite'
50
-
51
- export default {
52
- plugins: [
53
- one({ /* ... */ }),
54
- sootsimPlugin(),
55
- ],
56
- }
57
- `):console.log(`
58
- manual setup \u2014 add to your metro.config.js:
59
-
60
- const { withSootsim } = require('sootsim/metro')
61
- module.exports = withSootsim(config)
62
- `)}export{ce as a};
@@ -1,79 +0,0 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{d as ue,e as de,f as pe}from"./chunk-SX6BVZL5.js";import{d as ce}from"./chunk-TP3NTZUM.js";import{c as ae,e as le,g as P}from"./chunk-XWHR6IKV.js";import{d as ie}from"./chunk-T6QPOIJN.js";import{a as se,b as T}from"./chunk-KJOBH5CA.js";import{a as oe}from"./chunk-IEGRNKTT.js";import{createHash as He}from"crypto";import{readFileSync as K}from"fs";import{gzipSync as Ce}from"zlib";function fe(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}import{brotliCompressSync as Le,constants as Ee}from"node:zlib";var ke=9;function ge(e){return Le(e,{params:{[Ee.BROTLI_PARAM_QUALITY]:ke}})}function G(e,t){let r=new AbortController,o=setTimeout(()=>r.abort(new Error(`${t} timed out after ${e/1e3}s`)),e);return{signal:r.signal,cancel:()=>clearTimeout(o)}}async function Ae(e){let t=G(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 o=await r.text().catch(()=>"");throw new Error(`PUT ${e.url} failed ${r.status}: ${o.slice(0,200)}`)}}async function Fe(e,t=8,r){let o=0,i=0,a=e.length;await Promise.all(Array.from({length:Math.min(t,a)},async()=>{for(;o<a;){let c=e[o++];await Ae(c),i++,r?.(i,a)}}))}function ze(e,t,r,o){let i=[];i.push({url:e.bundle.putUrl,contentType:e.bundle.contentType,bytes:t});for(let a of e.files){let c=r.get(a.urlhash);c&&i.push({url:a.putUrl,contentType:a.contentType,bytes:c})}e.events&&o?.eventsBytes&&i.push({url:e.events.putUrl,contentType:e.events.contentType,bytes:o.eventsBytes}),e.flowVideo&&o?.videoBytes&&i.push({url:e.flowVideo.putUrl,contentType:e.flowVideo.contentType,bytes:o.videoBytes}),e.storage&&o?.storageBytes&&i.push({url:e.storage.putUrl,contentType:e.storage.contentType,bytes:o.storageBytes});for(let a of e.snapshots??[]){let c=o?.snapshotBytes?.get(a.id);c&&i.push({url:a.putUrl,contentType:a.contentType,bytes:c})}return i}function Me(e){return e.replace(/\/+$/,"")}var F=class extends Error{constructor(r,o,i,a=""){super(r);this.status=o;this.phase=i;this.responseText=a;this.name="PresignedUploadError"}};async function he(e){let t=Me(e.originBase),r={"content-type":"application/json"};e.authHeader&&(r.authorization=e.authHeader),e.adminBypassToken&&(r["x-soot-admin-upload-bypass"]=e.adminBypassToken);let o=G(3e4,"init"),i;try{i=await fetch(`${t}/api/preview/upload/init`,{method:"POST",headers:r,body:JSON.stringify(e.initBody),signal:o.signal})}finally{o.cancel()}if(!i.ok){let p=await i.text().catch(()=>"");throw new F(`init failed: ${i.status} ${p.slice(0,200)}`,i.status,"init",p)}let a=await i.json(),c=ze(a,e.bundleBytes,e.filesByHash,e.extras);await Fe(c,e.concurrency??8,e.onPutProgress);let y=G(3e4,"finalize"),u;try{u=await fetch(`${t}/api/preview/upload/finalize`,{method:"POST",headers:r,body:JSON.stringify({token:a.token}),signal:y.signal})}finally{y.cancel()}if(!u.ok){let p=await u.text().catch(()=>"");throw new F(`finalize failed: ${u.status} ${p.slice(0,200)}`,u.status,"finalize",p)}let S=await u.json();return{init:a,finalize:S}}function Ne(e){if(!e)return null;try{let t=JSON.parse(e);return typeof t.message=="string"&&t.message?t.message:null}catch{return null}}var be=process.env.SOOTSIM_UPLOAD_ORIGIN||"https://sootbean.com",ve=process.env.SOOTSIM_PREVIEW_ORIGIN||"https://sootsim.com",J="http://localhost:3000",We=2e3;async function Ve(e){if(e)return e;if(process.env.SOOTSIM_UPLOAD_ORIGIN)return process.env.SOOTSIM_UPLOAD_ORIGIN;try{let t=await fetch(`${J}/api/preview/upload/init`,{method:"OPTIONS",signal:AbortSignal.timeout(We)});if(t.ok||t.status===204||t.status===405)return J}catch{}return be}function x(e){return e.replace(/\/$/,"")}function qe(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 De(e){try{let t=new URL(e).hostname.toLowerCase();return t==="sootbean.com"||t.endsWith(".sootbean.com")}catch{return!1}}function Ge(e,t){return t?x(t):process.env.SOOTSIM_PREVIEW_ORIGIN?x(process.env.SOOTSIM_PREVIEW_ORIGIN):qe(e)?x(e):De(e)?x(ve):x(e)}function Ke(){console.log(`
3
- sootsim upload \u2014 publish the current recorded bundle as a /preview/<id> link
4
-
5
- usage:
6
- sootsim upload [--origin <url>] [--public-origin <url>] (--events <path> | --video <path>) [--screenshot <path>] [--owner <org> --repo <repo>] [--sim <sim>] [--open] [--assets-only]
7
-
8
- options:
9
- --origin <url> upload target (default: auto)
10
- prefers ${J} when available, otherwise
11
- falls back to ${be}
12
- override with SOOTSIM_UPLOAD_ORIGIN env var
13
- --public-origin <url>
14
- public /preview link origin (default: ${ve}
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
- required unless --video is present; previews must
19
- have replay or recording playback data
20
- --screenshot <path>
21
- path to a PNG thumbnail to attach to the share
22
- --video <path> path to a webm/mp4/gif flow recording. embedded inline
23
- in the pr sticky comment served at
24
- /api/preview/flow-video?id=<share-id>
25
- --video-duration-ms <ms>
26
- duration hint for attached flow video
27
- --owner <org> associate a session upload with a linked org repo
28
- --repo <repo> repo name for --owner; the signed-in user must belong
29
- to the local/org team that owns the link
30
- --sim <sim> target a specific sim (see: sootsim list)
31
- --open open the resulting /preview/<id> url in the browser
32
- --assets-only drop API/JSON/HTML records before upload; keep images,
33
- fonts, css, js, and binary blobs. live-data demos hit
34
- the real network at replay time instead of serving
35
- recorded API snapshots
36
- -h, --help
37
-
38
- examples:
39
- sootsim upload --events ./my-session.jsonl.gz
40
- sootsim upload --origin http://localhost:3000 --events ./my-session.jsonl.gz --open
41
- sootsim upload --video /tmp/soot-flow.webm --video-duration-ms 12000
42
- `)}function b(e,t){let r=e.findIndex(i=>i===t);if(r<0)return;let o=e[r+1];return e.splice(r,2),o}function ye(e,t){let r=e.findIndex(o=>o===t);return r<0?!1:(e.splice(r,1),!0)}function me(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 we(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 je(e){return/\.bundle($|\?)/.test(e)||/\.js($|\?)/.test(e)?"application/javascript":/\.zip($|\?)/.test(e)?"application/zip":"application/javascript"}function Je(e){try{return new URL(e).searchParams.get("appFonts")||""}catch{return""}}function Ye(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 Qe(e,t){let o=[];for(let i=0;i<t;i+=15e5){let a=Math.min(i+15e5,t),c=await P(e,`(window.__sootsimLastTransformedBundle?.text || "").slice(${i}, ${a})`);if(typeof c!="string")return null;o.push(c)}return o.join("")}function j(e){let t=new Map;for(let r of e)t.set(r.urlhash||r.url,r);return Array.from(t.values())}async function ht(e,t){(e.includes("--help")||e.includes("-h"))&&(Ke(),process.exit(0));let r=[...e],o=await Ve(b(r,"--origin")),i=Ge(o,b(r,"--public-origin")),a=b(r,"--events"),c=b(r,"--screenshot"),y=b(r,"--video"),u=b(r,"--video-duration-ms"),S=b(r,"--owner"),p=b(r,"--repo"),Ue=ye(r,"--open");(S&&!p||!S&&p)&&(console.error(" --owner and --repo must be provided together"),process.exit(1)),!a&&!y&&(console.error(" preview uploads require playback data: pass --events or --video.\n for a normal local preview, use `sootsim record --mode combined --open`\n or `sootsim flow --preview` instead of uploading a bundle-only snapshot."),process.exit(1));let Y=ye(r,"--assets-only"),Be=ae(r,{stripBooleanFlags:[],stripValueFlags:[]}),v=le(Be),l,Q=[],m=[],z=null;try{if(l=await P(v,'(typeof window.__sootsimCaptureBundle === "function") ? window.__sootsimCaptureBundle() : null'),l?.bundleUrl){let n=new URL(l.bundleUrl).origin,[s,h]=await Promise.all([P(v,`(window.__sootsimPreviewRecorder?.list?.(${JSON.stringify(n)}) || [])`),P(v,`(async () => {
43
- const list = window.__sootsimListWorkerFetchRecorder
44
- return typeof list === 'function'
45
- ? await list(${JSON.stringify(n)})
46
- : []
47
- })()`)]);Q=j([...s,...h]).filter(d=>{try{return!new URL(d.url).pathname.startsWith("/api/")}catch{return!0}});let L=await P(v,`(async () => {
48
- const rec = window.__sootsimPreviewRecorder
49
- const workerList = window.__sootsimListWorkerFetchRecorder
50
- return {
51
- main: rec?.list ? rec.list() : [],
52
- worker: typeof workerList === 'function' ? await workerList() : [],
53
- }
54
- })()`),_=(L?j([...L.main,...L.worker]):[]).filter(d=>{try{return new URL(d.url).origin!==n}catch{return!1}}),B=_.length>0?{count:_.length,totalBytes:_.reduce((d,O)=>d+(O.size||0),0)}:null;if(B&&B.count>0){console.log(` ${B.count} recorded cross-origin responses (${(B.totalBytes/1024).toFixed(1)} KiB)`);let d=await P(v,`(async () => {
55
- const rec = window.__sootsimPreviewRecorder
56
- const workerDump = window.__sootsimDumpWorkerFetchRecorder
57
- const bundleUrl = ${JSON.stringify(l.bundleUrl)}
58
- const keep = (r) => {
59
- try {
60
- const u = new URL(r.url)
61
- if (u.origin !== ${JSON.stringify(n)}) return true
62
- // bundle-origin api responses came from the rewritten
63
- // /__app-api proxy at record time (re-keyed by the
64
- // recorder's unwrap step). they need bodies attached the
65
- // same way as cross-origin records \u2014 direct re-fetch from
66
- // the dev server lacks the bundle's session cookies.
67
- if (r.url !== bundleUrl && u.pathname.startsWith('/api/')) return true
68
- return false
69
- } catch { return false }
70
- }
71
- return {
72
- main: rec?.dump ? rec.dump().filter(keep) : [],
73
- worker: typeof workerDump === 'function'
74
- ? (await workerDump()).filter(keep)
75
- : [],
76
- }
77
- })()`);if(m=j([...d.main,...d.worker]),Y){let O=m.length;m=m.filter(D=>me(D.contentType));let q=B.totalBytes-m.reduce((D,$e)=>D+($e.size||0),0);console.log(` --assets-only: kept ${m.length}/${O} records (dropped ${(q/1024).toFixed(1)} KiB of API responses)`)}}}l?.transformedBundle&&(z=await Qe(v,l.transformedBundle.byteLength))}finally{v.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.
78
- open the app you want to share first (e.g. sootsim open 8082), then run upload.`),process.exit(2));let f,M=!1;if(z!==null)f=new TextEncoder().encode(z),M=!0,console.log(` using post-transform bundle: ${(f.byteLength/1024).toFixed(1)} KiB`);else{let n=Ye(l.bundleUrl);n!==l.bundleUrl&&console.log(" forcing lazy=false for self-contained bundle"),console.log(` capturing: ${n}`),f=await we(n),console.log(` main bundle: ${(f.byteLength/1024).toFixed(1)} KiB`)}let E=Q.filter(n=>n.url!==l.bundleUrl);Y&&(E=E.filter(n=>me(n.contentType))),console.log(` fetching ${E.length} extra files\u2026`);let k=(await Promise.all(E.map(async n=>{try{let s=await we(n.url);return{...n,bytes:s}}catch(s){return console.error(` warning: failed to re-fetch ${n.url}: ${s instanceof Error?s.message:s}`),null}}))).filter(n=>!!n),Te=k.reduce((n,s)=>n+s.bytes.byteLength,0);console.log(` ${k.length} extra files: ${(Te/1024).toFixed(1)} KiB`);let U;a&&(U=K(a));let g;c&&(g=K(c),console.log(` attaching screenshot: ${(g.byteLength/1024).toFixed(1)} KiB`));let w,A,X;if(y){if(w=K(y),A=y.endsWith(".mp4")?"video/mp4":y.endsWith(".gif")?"image/gif":"video/webm",u){let n=Number(u);(!Number.isFinite(n)||n<=0)&&(console.error(` invalid --video-duration-ms: ${u}`),await T(),process.exit(1)),X=Math.round(n)}console.log(` attaching flow video: ${(w.byteLength/1024).toFixed(1)} KiB (${A})`)}let I=ue(),R=pe(I),Pe=oe();se({event:"preview_upload_started",identity:{userId:I?.kind==="session"?Pe?.user?.id??null:null,repoId:R?.repoId??null,installationId:R?.installationId??null},properties:{origin:o,hasAuth:!!I,authMode:I?.kind??"none",bundleBytes:f.byteLength,isTransformed:M,extraFiles:k.length,recordedFetches:m.length,hasEvents:!!U,hasScreenshot:!!g,hasVideo:!!w}}),I||(console.error(" preview uploads need auth."),console.error(" set SOOTSIM_API_KEY=sk_sootsim_..., run `sootsim login`, or use the soot github runner."),await T(),process.exit(1));let Ie=de(I),Re=(()=>{try{return new URL(l.bundleUrl).origin}catch{return null}})(),H=(n,s,h,L,re,_,B,d)=>{let O=fe(_),q=O?Ce(n):n;return{url:s,urlhash:h,method:L,bodyHash:re,requestVaryHash:d,contentType:_,responseHeaders:B,bytes:q,encoding:O?"gzip":void 0}},Z=[],C=Je(l.pageHref)||"";if(C){let n=await ce(C,{onStaged:({url:s,byteLength:h})=>console.log(` staged app font: ${s} (${(h/1024).toFixed(1)} KiB)`),onError:(s,h)=>console.error(` warning: failed to fetch app font ${s}: ${h instanceof Error?h.message:h}`)});for(let s of n)Z.push(H(Buffer.from(s.bytes),s.url,s.urlhash,"GET","-",s.contentType))}let N=[...k.map(n=>H(n.bytes,n.url,n.urlhash,"GET","-",n.contentType,n.responseHeaders,n.requestVaryHash)),...m.map(n=>H(Buffer.from(n.bodyBase64,"base64"),n.url,n.urlhash,n.method||"GET",n.bodyHash||"-",n.contentType,n.responseHeaders,n.requestVaryHash)),...Z],W=ge(f),_e=He("sha256").update(f).digest("hex");console.log(` bundle raw=${(f.byteLength/1024).toFixed(1)} KiB br=${(W.byteLength/1024).toFixed(1)} KiB`);let Oe={contentHash:_e,bundleSizeBytes:f.byteLength,bundleContentType:je(l.bundleUrl),bundleEncoding:"br",bundleOrigin:Re,runtimeVersion:l.runtimeVersion??void 0,appFonts:C||void 0,entry:l.entry,isTransformed:M,deviceSpec:l.deviceSpec,installationId:R?.installationId??void 0,repoId:R?.repoId,owner:S??R?.owner,repo:p??R?.repo,files:N.map(n=>({url:n.url,urlhash:n.urlhash,method:n.method,bodyHash:n.bodyHash,contentType:n.contentType,responseHeaders:n.responseHeaders,requestVaryHash:n.requestVaryHash,encoding:n.encoding,sizeBytes:n.bytes.byteLength})),events:U?{sizeBytes:U.byteLength}:void 0,snapshots:g?[{id:"landing",label:"Landing",kind:"landing",t:0,contentType:"image/png",sizeBytes:g.byteLength}]:void 0,flowVideo:w&&A?{sizeBytes:w.byteLength,contentType:A,durationMs:X}:void 0},ee=new Map;for(let n of N)ee.set(n.urlhash,n.bytes);let te=new Map;g&&te.set("landing",g);let xe=Date.now(),$=W.byteLength;for(let n of N)$+=n.bytes.byteLength;U&&($+=U.byteLength),g&&($+=g.byteLength),w&&($+=w.byteLength);let Se=`${x(o)}/api/preview/upload/init`;console.log(` init: ${Se}`);let V;try{let n=await he({originBase:o,initBody:Oe,bundleBytes:W,filesByHash:ee,extras:{eventsBytes:U,videoBytes:w,snapshotBytes:te},authHeader:Ie,concurrency:16});V=n.finalize;let s=1+n.init.files.length+(n.init.events?1:0)+n.init.snapshots.length+(n.init.flowVideo?1:0);console.log(` PUT ${s} objects in ${Date.now()-xe}ms (${($/1024).toFixed(1)} KiB)`)}catch(n){let s=n;s.phase==="init"&&s.status===401&&(console.error(" preview upload requires a valid login."),console.error(" run `sootsim login` and retry."),await T(),process.exit(1)),s.status===402&&(console.error(` ${Ne(s.responseText)??"preview uploads require Personal, Team, or an active trial \u2014 upgrade from the billing dialog."}`),await T(),process.exit(1)),console.error(` ${s.message??`${s.phase??"upload"} failed: ${String(n)}`}`),await T(),process.exit(1)}let ne=`${i}${V.url}`;console.log(`
79
- stored ${V.filesStored??0} extra files`),console.log(` preview: ${ne}`),Ue&&await ie(ne),await T()}export{Ve as a,Ge as b,ht as c};
@@ -1 +0,0 @@
1
- /*! sootsim v0.1.138 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */