sootsim 0.1.85 → 0.1.86

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 (145) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-T3DUH5YJ.js → agent-S3WLX5Z4.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-NSBF4THI.js → agent-wrapper-PFPEQTPG.js} +2 -2
  4. package/dist-cli/chunks/{assert-X3F7TRCZ.js → assert-RQD66YGE.js} +2 -2
  5. package/dist-cli/chunks/auto-bootstrap-PWF7OYCV.js +2 -0
  6. package/dist-cli/chunks/beta-2HH7F2DQ.js +2 -0
  7. package/dist-cli/chunks/{chunk-WGDL5V6C.js → chunk-2IYMBWHL.js} +1 -1
  8. package/dist-cli/chunks/{chunk-5DIGWOY7.js → chunk-3GCSX5H5.js} +1 -1
  9. package/dist-cli/chunks/{chunk-OISHLFON.js → chunk-3TNIXR6J.js} +1 -1
  10. package/dist-cli/chunks/{chunk-5N3V7OCG.js → chunk-535UNERF.js} +2 -2
  11. package/dist-cli/chunks/{chunk-G7CIZ5S3.js → chunk-5DFVKWYQ.js} +3 -3
  12. package/dist-cli/chunks/{chunk-GTAD6IUV.js → chunk-5NW6W7YF.js} +1 -1
  13. package/dist-cli/chunks/{chunk-EKXK3SWK.js → chunk-5ZYANOOI.js} +2 -2
  14. package/dist-cli/chunks/{chunk-BZL6D4TV.js → chunk-6A7IWFXR.js} +63 -62
  15. package/dist-cli/chunks/{chunk-BHZJ6RIH.js → chunk-6LG7WJMD.js} +2 -2
  16. package/dist-cli/chunks/{chunk-EFM53PZ5.js → chunk-7YZHI7V6.js} +1 -1
  17. package/dist-cli/chunks/{chunk-QLJNSOS7.js → chunk-CMAANHYQ.js} +1 -1
  18. package/dist-cli/chunks/{chunk-KUSQ4NNJ.js → chunk-CQAQTU5K.js} +1 -1
  19. package/dist-cli/chunks/{chunk-AFNDVS4E.js → chunk-CSJS4MRN.js} +2 -2
  20. package/dist-cli/chunks/{chunk-7LKUN46F.js → chunk-DKW7Q4F3.js} +2 -2
  21. package/dist-cli/chunks/{chunk-ZO3VHP6W.js → chunk-EDWDFOPL.js} +1 -1
  22. package/dist-cli/chunks/{chunk-EBEL6TTJ.js → chunk-FF5KD3BS.js} +2 -2
  23. package/dist-cli/chunks/{chunk-BESAZ2HA.js → chunk-FO52BFW4.js} +2 -2
  24. package/dist-cli/chunks/chunk-I3JMONYJ.js +2 -0
  25. package/dist-cli/chunks/{chunk-UYRGCJ4N.js → chunk-JB467MUR.js} +45 -45
  26. package/dist-cli/chunks/{chunk-SBGOUA6F.js → chunk-JBYW57OA.js} +2 -2
  27. package/dist-cli/chunks/{chunk-NVTL3JQG.js → chunk-JITAVV2G.js} +1 -1
  28. package/dist-cli/chunks/{chunk-O6N2CEET.js → chunk-JMILXXI4.js} +2 -2
  29. package/dist-cli/chunks/chunk-KGYC4SZA.js +2 -0
  30. package/dist-cli/chunks/{chunk-H44IQHKZ.js → chunk-KQYOS5SM.js} +1 -1
  31. package/dist-cli/chunks/{chunk-HQDJ5BOF.js → chunk-M6GOCS27.js} +1 -1
  32. package/dist-cli/chunks/{chunk-DWTLRPEN.js → chunk-NBBH2PVW.js} +2 -2
  33. package/dist-cli/chunks/chunk-NIRJVBXJ.js +1 -0
  34. package/dist-cli/chunks/{chunk-PHPXGLME.js → chunk-NLH7FNSG.js} +1 -1
  35. package/dist-cli/chunks/{chunk-Y5PLPEEU.js → chunk-OBHJKTWA.js} +2 -2
  36. package/dist-cli/chunks/{chunk-5S6D7K4L.js → chunk-OCTDP37S.js} +2 -2
  37. package/dist-cli/chunks/{chunk-OUNLJM56.js → chunk-P7IKKZTG.js} +2 -2
  38. package/dist-cli/chunks/{chunk-3WGHC7JN.js → chunk-PVMX5UNR.js} +2 -2
  39. package/dist-cli/chunks/chunk-QUYC7CVV.js +1 -0
  40. package/dist-cli/chunks/{chunk-CF2LPRXD.js → chunk-STHMWSVN.js} +2 -2
  41. package/dist-cli/chunks/{chunk-OXOARRKR.js → chunk-TSNBQ4ZV.js} +10 -10
  42. package/dist-cli/chunks/{chunk-E2QE5FFP.js → chunk-UWSP2AT7.js} +1 -1
  43. package/dist-cli/chunks/{chunk-4EVSIUNB.js → chunk-V7CFSKMC.js} +2 -2
  44. package/dist-cli/chunks/{chunk-4QZHZ6BC.js → chunk-VFGAEMSI.js} +2 -2
  45. package/dist-cli/chunks/{chunk-RZHREO3M.js → chunk-VUYCS6QI.js} +2 -2
  46. package/dist-cli/chunks/chunk-XB4QIINM.js +24 -0
  47. package/dist-cli/chunks/{chunk-MAO7F5PH.js → chunk-XFJYEKYK.js} +3 -3
  48. package/dist-cli/chunks/{chunk-AC6QGW22.js → chunk-XZE53P4L.js} +2 -2
  49. package/dist-cli/chunks/chunk-Y7BXSTVX.js +1 -0
  50. package/dist-cli/chunks/cli-version-TGWWTYQX.js +2 -0
  51. package/dist-cli/chunks/{compat-PCXGGZBZ.js → compat-I2U3P4KP.js} +3 -3
  52. package/dist-cli/chunks/{config-LULEVEYL.js → config-S73CCGP5.js} +2 -2
  53. package/dist-cli/chunks/{control-6P6HY7UF.js → control-QR6MY7RA.js} +2 -2
  54. package/dist-cli/chunks/{cpu-profile-NOK73ZYW.js → cpu-profile-RFYCTVAF.js} +2 -2
  55. package/dist-cli/chunks/{daemon-4A3DMUYL.js → daemon-D5MV2B22.js} +2 -2
  56. package/dist-cli/chunks/{debug-74BWB2ZG.js → debug-ZYEI75AG.js} +3 -3
  57. package/dist-cli/chunks/{detox-HEOMINSC.js → detox-J5IH52RV.js} +2 -2
  58. package/dist-cli/chunks/{device-TTXXBJFZ.js → device-NOBLSUOD.js} +2 -2
  59. package/dist-cli/chunks/{diagnose-QZ3GOHSE.js → diagnose-B6J5ZUHV.js} +2 -2
  60. package/dist-cli/chunks/drivers-RRHVOU6S.js +2 -0
  61. package/dist-cli/chunks/{electron-QVOWV44R.js → electron-PSX4KDCC.js} +3 -3
  62. package/dist-cli/chunks/flow-FWNVFKMP.js +2 -0
  63. package/dist-cli/chunks/{hints-YKWRNMJC.js → hints-ZE4I3YO3.js} +2 -2
  64. package/dist-cli/chunks/{home-paths-SFADSTJM.js → home-paths-N76MJE3D.js} +2 -2
  65. package/dist-cli/chunks/{inspect-LEWGQCIU.js → inspect-V2TXTDOG.js} +3 -3
  66. package/dist-cli/chunks/install-4PINRR2O.js +2 -0
  67. package/dist-cli/chunks/{install-desktop-22HYQZ2G.js → install-desktop-6ZRTRRCU.js} +3 -3
  68. package/dist-cli/chunks/{keys-3ZT3MICU.js → keys-L2RN4URM.js} +2 -2
  69. package/dist-cli/chunks/{launch-ZXW2NFLG.js → launch-BJGXPNZR.js} +3 -3
  70. package/dist-cli/chunks/{login-NJKJ7GZO.js → login-HYNEMAYR.js} +4 -4
  71. package/dist-cli/chunks/{logout-VMMQL7CB.js → logout-AO4YS27T.js} +2 -2
  72. package/dist-cli/chunks/{maestro-OJY4MTI7.js → maestro-PRACYFKV.js} +2 -2
  73. package/dist-cli/chunks/{preview-QU2GXTEV.js → preview-ZTANXVEK.js} +2 -2
  74. package/dist-cli/chunks/{profile-7APWK47T.js → profile-FNMAGUDB.js} +2 -2
  75. package/dist-cli/chunks/{react-RSVO5JZZ.js → react-6ZV2FQIM.js} +2 -2
  76. package/dist-cli/chunks/{record-UWH4MDEO.js → record-MLFVJZ6Y.js} +2 -2
  77. package/dist-cli/chunks/runtime-5762IE56.js +2 -0
  78. package/dist-cli/chunks/{runtime-delivery-QMKGRV7N.js → runtime-delivery-ATYW2SQR.js} +2 -2
  79. package/dist-cli/chunks/{screenshot-43M27ALE.js → screenshot-UOMYMFZ4.js} +2 -2
  80. package/dist-cli/chunks/{screenshot-mode-EBYYN6TY.js → screenshot-mode-MWSVD4YG.js} +2 -2
  81. package/dist-cli/chunks/{screenshots-7TQZL6Z6.js → screenshots-GSA3VCWB.js} +2 -2
  82. package/dist-cli/chunks/server-YPFC6POG.js +40 -0
  83. package/dist-cli/chunks/setup-repo-QBQ4VWFO.js +2 -0
  84. package/dist-cli/chunks/{skills-RQA6EJQL.js → skills-YE5OPWMQ.js} +2 -2
  85. package/dist-cli/chunks/{start-ZT6MBYND.js → start-BSSQ5U2V.js} +4 -4
  86. package/dist-cli/chunks/store-EG4SONAH.js +2 -0
  87. package/dist-cli/chunks/telemetry-XXN4LRDS.js +2 -0
  88. package/dist-cli/chunks/{test-RNRX5SWV.js → test-5JMLBH2O.js} +3 -3
  89. package/dist-cli/chunks/{three-mode-TQZH25ZO.js → three-mode-TRBWZJQY.js} +2 -2
  90. package/dist-cli/chunks/{timeline-GGN3AY6P.js → timeline-YMZPIEB4.js} +2 -2
  91. package/dist-cli/chunks/{upgrade-XT22D67C.js → upgrade-JLAS7FIF.js} +2 -2
  92. package/dist-cli/chunks/upload-K6UNCFQH.js +2 -0
  93. package/dist-cli/chunks/{web-KEHVF5MB.js → web-D6S5UXOO.js} +2 -2
  94. package/dist-cli/chunks/{what-happened-PATQRJ5T.js → what-happened-65NXWU2S.js} +2 -2
  95. package/dist-cli/chunks/{whoami-CXVY26VV.js → whoami-6BSB6FQC.js} +2 -2
  96. package/dist-lib/agent-daemon-client.cjs +1 -1
  97. package/dist-lib/agent-events.cjs +1 -1
  98. package/dist-lib/agent-sessions.cjs +1 -1
  99. package/dist-lib/attached-projects.cjs +1 -1
  100. package/dist-lib/auth/shared-session.cjs +1 -1
  101. package/dist-lib/backend-origin.cjs +1 -1
  102. package/dist-lib/beta.cjs +1 -1
  103. package/dist-lib/beta.mjs +15 -0
  104. package/dist-lib/bridge-constants.cjs +1 -1
  105. package/dist-lib/cli-constants.cjs +1 -1
  106. package/dist-lib/config.cjs +1 -1
  107. package/dist-lib/detox/index.cjs +1 -1
  108. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  109. package/dist-lib/home-paths.cjs +1 -1
  110. package/dist-lib/host/bridge-host.cjs +244 -35
  111. package/dist-lib/host/fetch-proxy-handler.cjs +24 -4
  112. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  113. package/dist-lib/host/fetch-proxy-overrides.mjs +33 -0
  114. package/dist-lib/host/websocket-proxy.cjs +207 -0
  115. package/dist-lib/index.cjs +1 -1
  116. package/dist-lib/metro.cjs +1 -1
  117. package/dist-lib/profiles.cjs +1 -1
  118. package/dist-lib/render-mode.cjs +1 -1
  119. package/dist-lib/scripts/demo-app-registry.cjs +14 -3
  120. package/dist-lib/scripts/dev-server-scanner.cjs +14 -3
  121. package/dist-lib/skills.cjs +290 -73
  122. package/dist-lib/vite.cjs +1 -1
  123. package/package.json +7 -1
  124. package/scripts/demo-app-registry.ts +17 -1
  125. package/src/host/bridge-host.ts +8 -1
  126. package/src/host/fetch-proxy-handler.ts +26 -3
  127. package/src/host/websocket-proxy.ts +201 -0
  128. package/dist-cli/chunks/auto-bootstrap-47RN2V5G.js +0 -2
  129. package/dist-cli/chunks/beta-BRCGAF2N.js +0 -2
  130. package/dist-cli/chunks/chunk-36RPD6JI.js +0 -2
  131. package/dist-cli/chunks/chunk-4DBPNLGI.js +0 -1
  132. package/dist-cli/chunks/chunk-PQFFUJR6.js +0 -24
  133. package/dist-cli/chunks/chunk-QQAECG5B.js +0 -2
  134. package/dist-cli/chunks/chunk-SSCA2AEA.js +0 -1
  135. package/dist-cli/chunks/chunk-ZFAM4N5B.js +0 -1
  136. package/dist-cli/chunks/cli-version-WPFDM2A6.js +0 -2
  137. package/dist-cli/chunks/drivers-QRPWNOIT.js +0 -2
  138. package/dist-cli/chunks/flow-QMA7GVN6.js +0 -2
  139. package/dist-cli/chunks/install-7N2N7Q32.js +0 -2
  140. package/dist-cli/chunks/runtime-3FUENRHM.js +0 -2
  141. package/dist-cli/chunks/server-VCFM25Z6.js +0 -35
  142. package/dist-cli/chunks/setup-repo-HFH4VKJQ.js +0 -2
  143. package/dist-cli/chunks/store-BJBTDSZE.js +0 -2
  144. package/dist-cli/chunks/telemetry-ZZZKTILZ.js +0 -2
  145. package/dist-cli/chunks/upload-NC2AYLC5.js +0 -2
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.85 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.86 | (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;
@@ -32,6 +32,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
  // src/host/fetch-proxy-handler.ts
33
33
  var fetch_proxy_handler_exports = {};
34
34
  __export(fetch_proxy_handler_exports, {
35
+ buildAppApiProxyHeaders: () => buildAppApiProxyHeaders,
35
36
  buildFetchProxyHeaders: () => buildFetchProxyHeaders,
36
37
  handleAppApiRequest: () => handleAppApiRequest,
37
38
  handleFetchProxyRequest: () => handleFetchProxyRequest,
@@ -97,6 +98,14 @@ var FETCH_PROXY_CORS_HEADERS = {
97
98
  "access-control-expose-headers": "*",
98
99
  "access-control-max-age": "3600"
99
100
  };
101
+ var APP_API_HEADER_REWRITES = /* @__PURE__ */ new Set([
102
+ "host",
103
+ "origin",
104
+ "referer",
105
+ "sec-fetch-site",
106
+ "sec-fetch-mode",
107
+ "sec-fetch-dest"
108
+ ]);
100
109
  function applyFetchProxyCors(res) {
101
110
  for (const [key, value] of Object.entries(FETCH_PROXY_CORS_HEADERS)) {
102
111
  res.setHeader(key, value);
@@ -129,6 +138,18 @@ function buildFetchProxyHeaders(reqHeaders, targetUrl) {
129
138
  );
130
139
  return headers;
131
140
  }
141
+ function buildAppApiProxyHeaders(reqHeaders, targetUrl) {
142
+ const headers = {};
143
+ for (const [key, value] of Object.entries(reqHeaders)) {
144
+ if (!value) continue;
145
+ if (APP_API_HEADER_REWRITES.has(key.toLowerCase())) continue;
146
+ headers[key] = value;
147
+ }
148
+ headers.host = targetUrl.host;
149
+ headers.origin = targetUrl.origin;
150
+ headers.referer = `${targetUrl.origin}/`;
151
+ return headers;
152
+ }
132
153
  function isFetchProxyRequestUrl(rawUrl) {
133
154
  return rawUrl?.startsWith("/__fetch-proxy?") || rawUrl?.startsWith("/__proxy?") || false;
134
155
  }
@@ -239,9 +260,7 @@ function handleAppApiRequest(req, res) {
239
260
  return true;
240
261
  }
241
262
  const transport = targetUrl.protocol === "https:" ? import_https.default : import_http.default;
242
- const fwdHeaders = { ...req.headers };
243
- delete fwdHeaders.host;
244
- fwdHeaders.host = targetUrl.host;
263
+ const fwdHeaders = buildAppApiProxyHeaders(req.headers, targetUrl);
245
264
  const proxyReq = transport.request(
246
265
  {
247
266
  hostname: targetUrl.hostname,
@@ -273,6 +292,7 @@ function handleAppApiRequest(req, res) {
273
292
  }
274
293
  // Annotate the CommonJS export names for ESM import in node:
275
294
  0 && (module.exports = {
295
+ buildAppApiProxyHeaders,
276
296
  buildFetchProxyHeaders,
277
297
  handleAppApiRequest,
278
298
  handleFetchProxyRequest,
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.85 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.86 | (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 __defProp = Object.defineProperty;
@@ -0,0 +1,33 @@
1
+ /*! sootsim v0.1.86 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+
3
+ // src/host/fetch-proxy-overrides.ts
4
+ var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
5
+ var HOST_HEADER_OVERRIDES = [
6
+ {
7
+ hostSuffix: "uniswap.org",
8
+ headers: {
9
+ origin: "https://app.uniswap.org",
10
+ referer: "https://app.uniswap.org/"
11
+ }
12
+ }
13
+ ];
14
+ function headerOverridesFor(hostname) {
15
+ const host = hostname.toLowerCase();
16
+ for (const override of HOST_HEADER_OVERRIDES) {
17
+ if (host === override.hostSuffix || host.endsWith(`.${override.hostSuffix}`)) {
18
+ return override.headers;
19
+ }
20
+ }
21
+ return {};
22
+ }
23
+ function getFetchProxyTargetHeaders(targetUrl) {
24
+ return {
25
+ "accept-encoding": "identity",
26
+ "user-agent": FETCH_PROXY_BROWSER_USER_AGENT,
27
+ ...headerOverridesFor(targetUrl.hostname)
28
+ };
29
+ }
30
+ export {
31
+ FETCH_PROXY_BROWSER_USER_AGENT,
32
+ getFetchProxyTargetHeaders
33
+ };
@@ -0,0 +1,207 @@
1
+ /*! sootsim v0.1.86 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
+ "use strict";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/host/websocket-proxy.ts
23
+ var websocket_proxy_exports = {};
24
+ __export(websocket_proxy_exports, {
25
+ WEBSOCKET_PROXY_PATH: () => WEBSOCKET_PROXY_PATH,
26
+ handleWebSocketProxyUpgrade: () => handleWebSocketProxyUpgrade,
27
+ isWebSocketProxyRequestUrl: () => isWebSocketProxyRequestUrl
28
+ });
29
+ module.exports = __toCommonJS(websocket_proxy_exports);
30
+ var import_ws = require("ws");
31
+ var WEBSOCKET_PROXY_PATH = "/__websocket-proxy";
32
+ var STRIP_UPSTREAM_HEADERS = /* @__PURE__ */ new Set([
33
+ "host",
34
+ "connection",
35
+ "upgrade",
36
+ "transfer-encoding",
37
+ "content-length",
38
+ "sec-websocket-accept",
39
+ "sec-websocket-extensions",
40
+ "sec-websocket-key",
41
+ "sec-websocket-protocol",
42
+ "sec-websocket-version"
43
+ ]);
44
+ function rejectUpgrade(socket, status, message) {
45
+ try {
46
+ socket.write(
47
+ `HTTP/1.1 ${status} ${message}\r
48
+ Connection: close\r
49
+ Content-Type: text/plain\r
50
+ Content-Length: ${message.length}\r
51
+ \r
52
+ ${message}`
53
+ );
54
+ } catch {
55
+ }
56
+ socket.destroy();
57
+ }
58
+ function isSameOriginUpgrade(req) {
59
+ const origin = req.headers.origin;
60
+ const host = req.headers.host;
61
+ if (!origin || !host) return false;
62
+ try {
63
+ return new URL(origin).host === host;
64
+ } catch {
65
+ return false;
66
+ }
67
+ }
68
+ function decodeProxyHeaders(encoded) {
69
+ if (!encoded) return {};
70
+ const base64 = encoded.replace(/-/g, "+").replace(/_/g, "/");
71
+ const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
72
+ const parsed = JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
73
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
74
+ const headers = {};
75
+ for (const [key, value] of Object.entries(parsed)) {
76
+ if (value == null) continue;
77
+ if (STRIP_UPSTREAM_HEADERS.has(key.toLowerCase())) continue;
78
+ headers[key] = Array.isArray(value) ? value.join(", ") : String(value);
79
+ }
80
+ return headers;
81
+ }
82
+ function getDefaultWebSocketOrigin(targetUrl) {
83
+ const origin = new URL(targetUrl.href);
84
+ origin.protocol = targetUrl.protocol === "wss:" ? "https:" : "http:";
85
+ return origin.origin;
86
+ }
87
+ function getRequestedProtocols(req) {
88
+ const header = req.headers["sec-websocket-protocol"];
89
+ const value = Array.isArray(header) ? header.join(",") : header || "";
90
+ return value.split(",").map((part) => part.trim()).filter(Boolean);
91
+ }
92
+ function safeClose(ws, code, reason) {
93
+ if (ws.readyState === import_ws.WebSocket.CLOSED || ws.readyState === import_ws.WebSocket.CLOSING) {
94
+ return;
95
+ }
96
+ try {
97
+ ws.close(code, reason);
98
+ } catch {
99
+ ws.terminate();
100
+ }
101
+ }
102
+ function connectProxyPair(clientWs, upstream) {
103
+ let closing = false;
104
+ const closeBoth = (source, target, code, reason) => {
105
+ if (closing) return;
106
+ closing = true;
107
+ safeClose(target, code, reason.toString());
108
+ if (source.readyState === import_ws.WebSocket.OPEN) {
109
+ safeClose(source, code, reason.toString());
110
+ }
111
+ };
112
+ clientWs.on("message", (data, isBinary) => {
113
+ if (upstream.readyState === import_ws.WebSocket.OPEN) {
114
+ upstream.send(data, { binary: isBinary });
115
+ }
116
+ });
117
+ upstream.on("message", (data, isBinary) => {
118
+ if (clientWs.readyState === import_ws.WebSocket.OPEN) {
119
+ clientWs.send(data, { binary: isBinary });
120
+ }
121
+ });
122
+ clientWs.on("close", (code, reason) => closeBoth(clientWs, upstream, code, reason));
123
+ upstream.on("close", (code, reason) => closeBoth(upstream, clientWs, code, reason));
124
+ clientWs.on("error", () => safeClose(upstream, 1011, "proxy client error"));
125
+ upstream.on("error", () => safeClose(clientWs, 1011, "upstream websocket error"));
126
+ }
127
+ function createUpstreamWebSocket(targetUrl, protocols, headers) {
128
+ const upstreamHeaders = { ...headers };
129
+ if (!Object.keys(upstreamHeaders).some((key) => key.toLowerCase() === "origin")) {
130
+ upstreamHeaders.origin = getDefaultWebSocketOrigin(targetUrl);
131
+ }
132
+ return new import_ws.WebSocket(targetUrl.href, protocols, {
133
+ headers: upstreamHeaders
134
+ });
135
+ }
136
+ function isWebSocketProxyRequestUrl(rawUrl) {
137
+ if (!rawUrl) return false;
138
+ try {
139
+ return new URL(rawUrl, "http://localhost").pathname === WEBSOCKET_PROXY_PATH;
140
+ } catch {
141
+ return false;
142
+ }
143
+ }
144
+ function handleWebSocketProxyUpgrade(req, socket, head) {
145
+ if (!isWebSocketProxyRequestUrl(req.url)) return false;
146
+ if (!isSameOriginUpgrade(req)) {
147
+ rejectUpgrade(socket, 403, "forbidden websocket proxy origin");
148
+ return true;
149
+ }
150
+ let targetUrl;
151
+ let headers;
152
+ try {
153
+ const requestUrl = new URL(req.url || "/", "http://localhost");
154
+ const target = requestUrl.searchParams.get("url");
155
+ if (!target) {
156
+ rejectUpgrade(socket, 400, "missing websocket proxy url");
157
+ return true;
158
+ }
159
+ targetUrl = new URL(target);
160
+ if (targetUrl.protocol !== "ws:" && targetUrl.protocol !== "wss:") {
161
+ rejectUpgrade(socket, 400, "invalid websocket proxy protocol");
162
+ return true;
163
+ }
164
+ headers = decodeProxyHeaders(requestUrl.searchParams.get("headers"));
165
+ } catch {
166
+ rejectUpgrade(socket, 400, "invalid websocket proxy request");
167
+ return true;
168
+ }
169
+ const protocols = getRequestedProtocols(req);
170
+ const upstream = createUpstreamWebSocket(targetUrl, protocols, headers);
171
+ let completed = false;
172
+ socket.once("close", () => {
173
+ if (!completed) upstream.terminate();
174
+ });
175
+ upstream.once("open", () => {
176
+ if (completed) return;
177
+ completed = true;
178
+ const selectedProtocol = upstream.protocol;
179
+ const proxyServer = new import_ws.WebSocketServer({
180
+ noServer: true,
181
+ clientTracking: false,
182
+ handleProtocols(requestedProtocols) {
183
+ return selectedProtocol || requestedProtocols.values().next().value || false;
184
+ }
185
+ });
186
+ proxyServer.handleUpgrade(req, socket, head, (clientWs) => {
187
+ connectProxyPair(clientWs, upstream);
188
+ });
189
+ });
190
+ upstream.once("error", () => {
191
+ if (completed) return;
192
+ completed = true;
193
+ rejectUpgrade(socket, 502, "upstream websocket error");
194
+ });
195
+ upstream.once("close", () => {
196
+ if (completed) return;
197
+ completed = true;
198
+ rejectUpgrade(socket, 502, "upstream websocket closed");
199
+ });
200
+ return true;
201
+ }
202
+ // Annotate the CommonJS export names for ESM import in node:
203
+ 0 && (module.exports = {
204
+ WEBSOCKET_PROXY_PATH,
205
+ handleWebSocketProxyUpgrade,
206
+ isWebSocketProxyRequestUrl
207
+ });
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.85 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.86 | (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;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.85 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.86 | (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;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.85 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.86 | (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;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.85 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.86 | (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 __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.85 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.86 | (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 __defProp = Object.defineProperty;
@@ -593,11 +593,22 @@ var APPS = [
593
593
  // be holding pglite locks on ~/takeout/.orez (soot can attach takeout as
594
594
  // a project and spin up its own orez against the same data dir).
595
595
  readyTimeoutMs: 24e4,
596
+ managedPorts: (p) => {
597
+ const offset = p - 8081;
598
+ return [5433 + offset, 4848 + offset, 9200 + offset];
599
+ },
596
600
  command: (p) => ({
597
- cmd: "bun lite",
601
+ cmd: "bun lite:demo",
598
602
  env: {
603
+ TAKEOUT_ENV_MODE: "development",
599
604
  PORT_OFFSET: String(p - 8081),
600
- OREZ_DATA_DIR: `${HOME}/.cache/sootsim-demo/takeout-orez`
605
+ OREZ_DATA_DIR: `${HOME}/.cache/sootsim-demo/takeout-orez`,
606
+ VITE_DEMO_MODE: "1",
607
+ ZERO_APP_ID: "takeout",
608
+ ZERO_APP_PUBLICATIONS: "zero_takeout",
609
+ ZERO_CVR_MAX_CONNS: "4",
610
+ ZERO_NUM_SYNC_WORKERS: "2",
611
+ ZERO_UPSTREAM_MAX_CONNS: "8"
601
612
  }
602
613
  })
603
614
  },
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.85 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.86 | (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;
@@ -663,11 +663,22 @@ var APPS = [
663
663
  // be holding pglite locks on ~/takeout/.orez (soot can attach takeout as
664
664
  // a project and spin up its own orez against the same data dir).
665
665
  readyTimeoutMs: 24e4,
666
+ managedPorts: (p) => {
667
+ const offset = p - 8081;
668
+ return [5433 + offset, 4848 + offset, 9200 + offset];
669
+ },
666
670
  command: (p) => ({
667
- cmd: "bun lite",
671
+ cmd: "bun lite:demo",
668
672
  env: {
673
+ TAKEOUT_ENV_MODE: "development",
669
674
  PORT_OFFSET: String(p - 8081),
670
- OREZ_DATA_DIR: `${HOME}/.cache/sootsim-demo/takeout-orez`
675
+ OREZ_DATA_DIR: `${HOME}/.cache/sootsim-demo/takeout-orez`,
676
+ VITE_DEMO_MODE: "1",
677
+ ZERO_APP_ID: "takeout",
678
+ ZERO_APP_PUBLICATIONS: "zero_takeout",
679
+ ZERO_CVR_MAX_CONNS: "4",
680
+ ZERO_NUM_SYNC_WORKERS: "2",
681
+ ZERO_UPSTREAM_MAX_CONNS: "8"
671
682
  }
672
683
  })
673
684
  },