sootsim 0.1.218 → 0.1.220

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 (150) hide show
  1. package/README.md +5 -3
  2. package/detox/index.ts +6 -7
  3. package/dist-cli/bin.js +4 -4
  4. package/dist-cli/chunks/{agent-TQJDQNML.js → agent-LCKEPMVH.js} +2 -2
  5. package/dist-cli/chunks/{agent-wrapper-OAOFXHX2.js → agent-wrapper-ND5JHQSI.js} +2 -2
  6. package/dist-cli/chunks/{app-fonts-4VPAP3RZ.js → app-fonts-N2W5BQXE.js} +2 -2
  7. package/dist-cli/chunks/{assert-DKNRGH4M.js → assert-O3QO4ZFV.js} +2 -2
  8. package/dist-cli/chunks/{auth-ZYOAQEI2.js → auth-7VXPQOZP.js} +2 -2
  9. package/dist-cli/chunks/beta-ZIOECOJB.js +2 -0
  10. package/dist-cli/chunks/{camera-BJCRYG27.js → camera-OROQGFMH.js} +2 -2
  11. package/dist-cli/chunks/chunk-3HJXCSYI.js +119 -0
  12. package/dist-cli/chunks/{chunk-SXS5SPIZ.js → chunk-3ZWOQPLC.js} +1 -1
  13. package/dist-cli/chunks/{chunk-Q7U5TPQN.js → chunk-4JSQTD75.js} +1 -1
  14. package/dist-cli/chunks/{chunk-RZMI7IKL.js → chunk-64GMEXIP.js} +2 -2
  15. package/dist-cli/chunks/{chunk-JDCABF7Y.js → chunk-6HBN4KIM.js} +2 -2
  16. package/dist-cli/chunks/{chunk-B4KB5TBV.js → chunk-7TOHX4IF.js} +1 -1
  17. package/dist-cli/chunks/chunk-AMUOGO6F.js +1 -0
  18. package/dist-cli/chunks/{chunk-YMFQOXT4.js → chunk-BI3I5X3U.js} +1 -1
  19. package/dist-cli/chunks/{chunk-XB6FCXX3.js → chunk-BXNMPK4X.js} +2 -2
  20. package/dist-cli/chunks/{chunk-OTCJCVFR.js → chunk-EFLOJBBN.js} +3 -3
  21. package/dist-cli/chunks/{chunk-T2NAWDMZ.js → chunk-F5XBOFGK.js} +2 -2
  22. package/dist-cli/chunks/{chunk-FEMAFOUH.js → chunk-FRQOTDD6.js} +2 -2
  23. package/dist-cli/chunks/{chunk-F5H6XTMN.js → chunk-GBALEYV4.js} +1 -1
  24. package/dist-cli/chunks/{chunk-Q7K5GJR4.js → chunk-GWQWCFMR.js} +2 -2
  25. package/dist-cli/chunks/{chunk-IKZ4Z6ND.js → chunk-H7EGEWCF.js} +1 -1
  26. package/dist-cli/chunks/{chunk-AY5S4CWZ.js → chunk-HAXE5SZL.js} +1 -1
  27. package/dist-cli/chunks/{chunk-FAUOGIHF.js → chunk-J3QE2UZI.js} +1 -1
  28. package/dist-cli/chunks/{chunk-NN7XOWXY.js → chunk-JMXBQ4RD.js} +3 -3
  29. package/dist-cli/chunks/{chunk-CMGPYPUE.js → chunk-KJVNP5B5.js} +2 -2
  30. package/dist-cli/chunks/{chunk-24FHNNST.js → chunk-KZUGDZ3Q.js} +6 -6
  31. package/dist-cli/chunks/{chunk-MW3G72KG.js → chunk-NPK2TDEV.js} +91 -14
  32. package/dist-cli/chunks/{chunk-73WAFGRP.js → chunk-NRHZHQOH.js} +2 -2
  33. package/dist-cli/chunks/{chunk-6WWKUDWP.js → chunk-OBWXIGPP.js} +2 -2
  34. package/dist-cli/chunks/{chunk-AK4CONMS.js → chunk-OCEYXYKG.js} +2 -2
  35. package/dist-cli/chunks/{chunk-ZJI2JP7F.js → chunk-PJ76I3KZ.js} +1 -1
  36. package/dist-cli/chunks/{chunk-V64N734Y.js → chunk-PWLK4BGI.js} +2 -2
  37. package/dist-cli/chunks/{chunk-TGXLBFTC.js → chunk-RIB5CQ34.js} +1 -1
  38. package/dist-cli/chunks/{chunk-CRPOEKYT.js → chunk-RTZNRPD4.js} +3 -3
  39. package/dist-cli/chunks/{chunk-7NP5BWIH.js → chunk-RWJM23VH.js} +1 -1
  40. package/dist-cli/chunks/{chunk-EEUNNW2P.js → chunk-S6XSCI45.js} +1 -1
  41. package/dist-cli/chunks/{chunk-QWJG2WVA.js → chunk-TEFCJZH5.js} +1 -1
  42. package/dist-cli/chunks/{chunk-LIR2VPPJ.js → chunk-TH7ODXC5.js} +9 -9
  43. package/dist-cli/chunks/{chunk-4DLUGQXQ.js → chunk-U3OSSCTT.js} +3 -3
  44. package/dist-cli/chunks/{chunk-AHTGZMT4.js → chunk-UHEKB33X.js} +2 -2
  45. package/dist-cli/chunks/{chunk-DVZVP32W.js → chunk-UODAA57Q.js} +2 -2
  46. package/dist-cli/chunks/{chunk-Z4QP44SI.js → chunk-UXLMOEFU.js} +2 -2
  47. package/dist-cli/chunks/{chunk-TNEHHCMZ.js → chunk-VCLV5GYE.js} +2 -2
  48. package/dist-cli/chunks/chunk-VQ4VGI36.js +1 -0
  49. package/dist-cli/chunks/{chunk-2HJU3NAO.js → chunk-XHPOQKUA.js} +1 -1
  50. package/dist-cli/chunks/{chunk-VOZZ62OJ.js → chunk-XKOYH7ES.js} +1 -1
  51. package/dist-cli/chunks/{chunk-L5HYRG4P.js → chunk-YRHLQY6J.js} +2 -2
  52. package/dist-cli/chunks/{chunk-CJHPCUUV.js → chunk-ZU6ECPCC.js} +1 -1
  53. package/dist-cli/chunks/{chunk-KLBOD2JL.js → chunk-ZW5IAKXC.js} +2 -2
  54. package/dist-cli/chunks/cli-version-MY4N7YDM.js +2 -0
  55. package/dist-cli/chunks/{compat-IETPHSZ3.js → compat-NRYECFCC.js} +3 -3
  56. package/dist-cli/chunks/{config-BOOBJ25W.js → config-4KKKEHH2.js} +2 -2
  57. package/dist-cli/chunks/{control-U52Q4YES.js → control-ZH7X66II.js} +2 -2
  58. package/dist-cli/chunks/daemon-6QQWVRFD.js +2 -0
  59. package/dist-cli/chunks/{debug-X4AW6CXJ.js → debug-Z66GNDYA.js} +3 -3
  60. package/dist-cli/chunks/{desktop-HHREMDE2.js → desktop-DO2BQKM4.js} +3 -3
  61. package/dist-cli/chunks/{detox-AXETJDTZ.js → detox-66YMXFQ5.js} +2 -2
  62. package/dist-cli/chunks/{device-B7PBIMER.js → device-KPQXKN5R.js} +2 -2
  63. package/dist-cli/chunks/{diagnose-7YEDF42J.js → diagnose-OMCHVX2X.js} +2 -2
  64. package/dist-cli/chunks/drivers-T2AZY5KL.js +2 -0
  65. package/dist-cli/chunks/{film-XQMAOELQ.js → film-PV6DPBRX.js} +3 -3
  66. package/dist-cli/chunks/flow-BCJH7MUK.js +2 -0
  67. package/dist-cli/chunks/help-KRIPS56R.js +2 -0
  68. package/dist-cli/chunks/{home-paths-I3NOFS6P.js → home-paths-LGQZZOPD.js} +2 -2
  69. package/dist-cli/chunks/inspect-3XG2QTVU.js +2 -0
  70. package/dist-cli/chunks/install-desktop-SH73YM3O.js +2 -0
  71. package/dist-cli/chunks/{login-O4ZPWWEU.js → login-QQH2UU2S.js} +4 -4
  72. package/dist-cli/chunks/{logout-REEPRXWZ.js → logout-KMGAWWAS.js} +2 -2
  73. package/dist-cli/chunks/{maestro-OCUCS5DY.js → maestro-IKINYBBR.js} +3 -3
  74. package/dist-cli/chunks/{maestro-generate-VHUHJFHR.js → maestro-generate-NWVVHDBL.js} +3 -3
  75. package/dist-cli/chunks/{mode-T24V4RZ4.js → mode-T576L6ZK.js} +2 -2
  76. package/dist-cli/chunks/optional-demo-registry-2F3PLJXV.js +2 -0
  77. package/dist-cli/chunks/{perf-ZUER6TVQ.js → perf-TRPZNIQH.js} +2 -2
  78. package/dist-cli/chunks/{record-XDKPMUBK.js → record-O5HUQAK4.js} +3 -3
  79. package/dist-cli/chunks/runtime-RLXYAF2A.js +2 -0
  80. package/dist-cli/chunks/{screenshot-command-MMUGPJ4I.js → screenshot-command-5FI7RD5L.js} +3 -3
  81. package/dist-cli/chunks/screenshots-capture-RLEAPJ45.js +41 -0
  82. package/dist-cli/chunks/{serve-BCATAS4S.js → serve-4SIWGY4S.js} +3 -3
  83. package/dist-cli/chunks/{setup-LXPQLQ6I.js → setup-LDHVGPS2.js} +9 -9
  84. package/dist-cli/chunks/{skills-OOPLWNI2.js → skills-CCIOVHHV.js} +2 -2
  85. package/dist-cli/chunks/{storage-E7MGHPIG.js → storage-HV7PNB7R.js} +2 -2
  86. package/dist-cli/chunks/store-DF56QJJG.js +2 -0
  87. package/dist-cli/chunks/telemetry-OFJVUJ34.js +2 -0
  88. package/dist-cli/chunks/{timeline-4AN6A5CV.js → timeline-NZY4TIYS.js} +2 -2
  89. package/dist-cli/chunks/upgrade-3SRHX5MN.js +4 -0
  90. package/dist-cli/chunks/upload-ZKKGG3CU.js +2 -0
  91. package/dist-cli/chunks/{version-LI2X5HLA.js → version-EWVUUOUL.js} +2 -2
  92. package/dist-cli/chunks/web-OT6OKUVX.js +2 -0
  93. package/dist-cli/chunks/{what-happened-2NTKQ4AT.js → what-happened-K2NQG7LZ.js} +2 -2
  94. package/dist-lib/agent-daemon-client.cjs +1 -1
  95. package/dist-lib/agent-events.cjs +1 -1
  96. package/dist-lib/agent-identity.cjs +1 -1
  97. package/dist-lib/agent-sessions.cjs +1 -1
  98. package/dist-lib/attached-projects.cjs +1 -1
  99. package/dist-lib/auth/shared-session.cjs +1 -1
  100. package/dist-lib/backend-origin.cjs +1 -1
  101. package/dist-lib/beta.cjs +1 -1
  102. package/dist-lib/beta.mjs +1 -1
  103. package/dist-lib/bridge-constants.cjs +1 -1
  104. package/dist-lib/cli-constants.cjs +1 -1
  105. package/dist-lib/config.cjs +1 -1
  106. package/dist-lib/detox/index.cjs +53 -7
  107. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  108. package/dist-lib/home-paths.cjs +1 -1
  109. package/dist-lib/host/bridge-host.cjs +14 -2
  110. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  111. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  112. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  113. package/dist-lib/host/websocket-proxy.cjs +1 -1
  114. package/dist-lib/index.cjs +1 -1
  115. package/dist-lib/jump-to-source-babel.cjs +1 -1
  116. package/dist-lib/menu.cjs +1 -1
  117. package/dist-lib/menu.mjs +1 -1
  118. package/dist-lib/metro.cjs +1 -1
  119. package/dist-lib/profiles.cjs +1 -1
  120. package/dist-lib/render-mode.cjs +1 -1
  121. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  122. package/dist-lib/sdk.cjs +1 -1
  123. package/dist-lib/sdk.mjs +1 -1
  124. package/dist-lib/skills.cjs +178 -22
  125. package/dist-lib/vite.cjs +1 -1
  126. package/package.json +1 -1
  127. package/src/host/bridge-host.ts +21 -1
  128. package/src/skills/builtin/a11y-review.ts +4 -1
  129. package/src/skills/builtin/perf-profile.ts +4 -1
  130. package/src/skills/builtin/screenshot-all.ts +4 -1
  131. package/src/skills/builtin/visual-diff.ts +4 -1
  132. package/dist-cli/chunks/beta-HL46FNX3.js +0 -2
  133. package/dist-cli/chunks/chunk-BZRIJJIK.js +0 -1
  134. package/dist-cli/chunks/chunk-FP3DRAKI.js +0 -119
  135. package/dist-cli/chunks/chunk-OUZAVYUG.js +0 -1
  136. package/dist-cli/chunks/cli-version-5FG6LIHX.js +0 -2
  137. package/dist-cli/chunks/daemon-EJDBU2UY.js +0 -2
  138. package/dist-cli/chunks/drivers-325S27FC.js +0 -2
  139. package/dist-cli/chunks/flow-V2SWGBAR.js +0 -2
  140. package/dist-cli/chunks/help-F4VH4LXF.js +0 -2
  141. package/dist-cli/chunks/inspect-NY5VGZNC.js +0 -2
  142. package/dist-cli/chunks/install-desktop-X7SXH7IN.js +0 -2
  143. package/dist-cli/chunks/optional-demo-registry-HPLGNZCO.js +0 -2
  144. package/dist-cli/chunks/runtime-4A24ALGX.js +0 -2
  145. package/dist-cli/chunks/screenshots-capture-OM6BE572.js +0 -41
  146. package/dist-cli/chunks/store-3DU64I7C.js +0 -2
  147. package/dist-cli/chunks/telemetry-AKRLP3AR.js +0 -2
  148. package/dist-cli/chunks/upgrade-FRBWFDPI.js +0 -4
  149. package/dist-cli/chunks/upload-XGUWNMYV.js +0 -2
  150. package/dist-cli/chunks/web-UDCVLGPU.js +0 -2
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.220 | (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;
@@ -103,8 +103,8 @@ var init_registry = __esm({
103
103
  range: ">=2.30.0",
104
104
  coverage: 0.9,
105
105
  note: "tap, pan, pinch, rotation, fling, long press, race, manual, simultaneous",
106
- working: "GestureDetector, Gesture.Tap/Pan/Pinch/Rotation/Fling/LongPress/Manual/Race/Simultaneous/Exclusive/Hover, ScrollView/FlatList, Switch/RefreshControl, Pressable/Text, Touchables, BaseButton/RawButton/RectButton/BorderlessButton/PureNativeButton, Swipeable, ReanimatedSwipeable, GestureHandlerRootView, createNativeWrapper, gestureHandlerRootHOC, PointerType/MouseButton/HoverEffect exports, velocity tracking, activeOffsets, multi-tap",
107
- missing: "DrawerLayout (passthrough noop), NativeViewGestureHandler still lacks native-scroll coupling and handlerTag semantics, cross-detector simultaneousWithExternalGesture/requireExternalGestureToFail, ForceTouch semantics are placeholder-only"
106
+ working: "GestureDetector, Gesture.Tap/Pan/Pinch/Rotation/Fling/LongPress/Manual/Race/Simultaneous/Exclusive/Hover, simultaneousWithExternalGesture/requireExternalGestureToFail/blocksExternalGesture, ScrollView/FlatList, Switch/RefreshControl, Pressable/Text, Touchables, BaseButton/RawButton/RectButton/BorderlessButton/PureNativeButton, Swipeable, ReanimatedSwipeable, GestureHandlerRootView, createNativeWrapper, gestureHandlerRootHOC, PointerType/MouseButton/HoverEffect exports, velocity tracking, activeOffsets, multi-tap",
107
+ missing: "DrawerLayout (passthrough noop), NativeViewGestureHandler still lacks native-scroll coupling and handlerTag semantics, ForceTouch semantics are placeholder-only"
108
108
  }
109
109
  ]
110
110
  },
@@ -128,7 +128,7 @@ var init_registry = __esm({
128
128
  versions: [
129
129
  {
130
130
  range: ">=4.0.0",
131
- coverage: 0.97,
131
+ coverage: 0.95,
132
132
  note: "live device/system-bar/ime metrics, edges/mode padding, hooks",
133
133
  working: "SafeAreaProvider with live Android system-bar and IME-resized frame metrics, SafeAreaView (edges/mode padding/margin), useSafeAreaInsets, useSafeAreaFrame, SafeAreaInsetsContext, SafeAreaFrameContext, initialWindowMetrics, SafeAreaListener onInsetsChange, withSafeAreaInsets HOC",
134
134
  missing: "rotation-specific provider frame deltas"
@@ -268,10 +268,10 @@ var init_registry = __esm({
268
268
  versions: [
269
269
  {
270
270
  range: ">=0.1.0",
271
- coverage: 0.93,
272
- note: "core thread-bridging APIs + runtime-kind type guards + runtime-id-keyed executors + shareable/synchronizable guards + custom serializable registry + feature flag readers all stubbed for sootsim semantics (one peer runtime via SAB-backed worklet runtime).",
273
- working: "runOnJS, runOnUI/Sync/Async, scheduleOnRN/UI/Runtime, runOnRuntime, runOnRuntimeAsync, runOnRuntimeSyncWithId, scheduleOnRuntimeWithId, makeShareable, createShareable (3-arg form with hostDecorator), createSerializable, createSynchronizable, isShareable, isSynchronizable, isWorkletFunction, isShareableRef, isSerializableRef, makeShareableCloneRecursive/OnUIRecursive, executeOnUIRuntimeSync, createWorkletRuntime, callMicrotasks, WorkletsModule, RuntimeKind enum, getRuntimeKind, isRNRuntime, isUIRuntime, isWorkerRuntime, isWorkletRuntime, UIRuntimeId, getUIRuntimeHolder, getUISchedulerHolder, registerCustomSerializable, getStaticFeatureFlag, getDynamicFeatureFlag, setDynamicFeatureFlag, Worklets namespace",
274
- missing: "cross-runtime structured-clone hooks for custom registered classes (registration is accepted but the SAB\u2194postMessage bridge does not consult it yet \u2014 apps that register custom classes still rely on structured-clone defaults), dynamic feature flag fan-out across the tenant\u2194shell split (setDynamicFeatureFlag is a noop write)"
271
+ coverage: 0.97,
272
+ note: "core RN\u2194UI thread bridging, isolated named Worker runtimes, runtime-kind guards, UI-runtime-id execution, shareable/synchronizable guards, custom serializable registration, and feature flag readers use SootSim worker runtimes.",
273
+ working: "createWorkletRuntime with isolated named Worker execution and lifecycle teardown, runOnRuntime/runOnRuntimeAsync/scheduleOnRuntime with scheduleOnRN callback return, runOnJS, runOnUI/Sync/Async, scheduleOnRN/UI, UI-runtime runOnRuntimeSyncWithId/scheduleOnRuntimeWithId, makeShareable, createShareable (3-arg form with hostDecorator), createSerializable, createSynchronizable, isShareable, isSynchronizable, isWorkletFunction, isShareableRef, isSerializableRef, makeShareableCloneRecursive/OnUIRecursive, executeOnUIRuntimeSync, callMicrotasks, WorkletsModule, RuntimeKind enum, getRuntimeKind, isRNRuntime, isUIRuntime, isWorkerRuntime, isWorkletRuntime, UIRuntimeId, getUIRuntimeHolder, getUISchedulerHolder, registerCustomSerializable, getStaticFeatureFlag, getDynamicFeatureFlag, setDynamicFeatureFlag, Worklets namespace",
274
+ missing: "synchronous named-runtime results, runtime-id scheduling into named workers, custom queue/event-loop configuration, cross-runtime structured-clone hooks for custom registered classes, dynamic feature flag fan-out across the tenant\u2194shell split"
275
275
  }
276
276
  ]
277
277
  },
@@ -11611,7 +11611,7 @@ function mkfifoSync(p) {
11611
11611
  import_node_fs4.default.unlinkSync(p);
11612
11612
  }
11613
11613
  }
11614
- const result = (0, import_node_child_process.spawnSync)("mkfifo", ["-m", "600", p]);
11614
+ const result = (0, import_node_child_process2.spawnSync)("mkfifo", ["-m", "600", p]);
11615
11615
  if (result.status !== 0) {
11616
11616
  throw new Error(
11617
11617
  `mkfifo(${p}) failed: ${result.stderr?.toString().trim() || "unknown error"}`
@@ -11679,7 +11679,7 @@ async function startSession(opts) {
11679
11679
  if (claudeSessionUuid) {
11680
11680
  wrapperArgs.push("--claude-session-uuid", claudeSessionUuid);
11681
11681
  }
11682
- const child = (0, import_node_child_process.spawn)(cmd, wrapperArgs, {
11682
+ const child = (0, import_node_child_process2.spawn)(cmd, wrapperArgs, {
11683
11683
  detached: true,
11684
11684
  stdio: "ignore",
11685
11685
  env: {
@@ -11827,11 +11827,11 @@ async function waitForFirstEvent(fifo, predicate, timeoutMs) {
11827
11827
  import_node_fs4.default.closeSync(fd);
11828
11828
  }
11829
11829
  }
11830
- var import_node_child_process, import_node_crypto2, import_node_fs4, import_node_path3, import_node_readline, AgentSessionError;
11830
+ var import_node_child_process2, import_node_crypto2, import_node_fs4, import_node_path3, import_node_readline, AgentSessionError;
11831
11831
  var init_agent_sessions = __esm({
11832
11832
  "src/agent-sessions.ts"() {
11833
11833
  "use strict";
11834
- import_node_child_process = require("node:child_process");
11834
+ import_node_child_process2 = require("node:child_process");
11835
11835
  import_node_crypto2 = require("node:crypto");
11836
11836
  import_node_fs4 = __toESM(require("node:fs"), 1);
11837
11837
  import_node_path3 = __toESM(require("node:path"), 1);
@@ -11892,7 +11892,7 @@ async function sendPromptToAgentbusSession(input) {
11892
11892
  const command = resolveAgentbusCommand(input.command);
11893
11893
  const timeoutMs = input.timeoutMs ?? 15e3;
11894
11894
  await new Promise((resolve5, reject) => {
11895
- const child = (0, import_node_child_process2.spawn)(command, ["send", sessionId, text], {
11895
+ const child = (0, import_node_child_process3.spawn)(command, ["send", sessionId, text], {
11896
11896
  stdio: ["ignore", "ignore", "pipe"],
11897
11897
  env: process.env
11898
11898
  });
@@ -11927,11 +11927,11 @@ async function sendPromptToAgentbusSession(input) {
11927
11927
  });
11928
11928
  });
11929
11929
  }
11930
- var import_node_child_process2, import_node_fs5, import_node_os2, import_node_path4;
11930
+ var import_node_child_process3, import_node_fs5, import_node_os2, import_node_path4;
11931
11931
  var init_agentbus_prompt = __esm({
11932
11932
  "src/agentbus-prompt.ts"() {
11933
11933
  "use strict";
11934
- import_node_child_process2 = require("node:child_process");
11934
+ import_node_child_process3 = require("node:child_process");
11935
11935
  import_node_fs5 = __toESM(require("node:fs"), 1);
11936
11936
  import_node_os2 = __toESM(require("node:os"), 1);
11937
11937
  import_node_path4 = __toESM(require("node:path"), 1);
@@ -13326,7 +13326,7 @@ var init_bridge_host = __esm({
13326
13326
  if (!this.wss) return;
13327
13327
  this.wss.on("connection", (ws, req) => {
13328
13328
  const origin = req.headers.origin;
13329
- const role = origin ? "sim" : "cli";
13329
+ let role = origin ? "sim" : "cli";
13330
13330
  let sim = null;
13331
13331
  ws.on("error", () => {
13332
13332
  });
@@ -13385,8 +13385,8 @@ var init_bridge_host = __esm({
13385
13385
  }
13386
13386
  if (msg.type === "runtime:use") {
13387
13387
  const version = typeof msg.version === "string" ? msg.version : "";
13388
- const installed = listInstalledRuntimes();
13389
- if (!installed.includes(version)) {
13388
+ const installed2 = listInstalledRuntimes();
13389
+ if (!installed2.includes(version)) {
13390
13390
  try {
13391
13391
  ws.send(
13392
13392
  JSON.stringify({
@@ -13428,6 +13428,18 @@ var init_bridge_host = __esm({
13428
13428
  }
13429
13429
  return;
13430
13430
  }
13431
+ if (role === "sim" && msg.type === "bridge:hello" && sim && !sim.url) {
13432
+ const provisionalId = sim.id;
13433
+ this.sims.delete(provisionalId);
13434
+ if (this.primarySimId === provisionalId) {
13435
+ this.primarySimId = this.getOpenSim()?.id ?? null;
13436
+ }
13437
+ sim = null;
13438
+ role = "cli";
13439
+ this.cliIdentityKeyBySocket.set(ws, `ws-${this.nextCliFallbackId++}`);
13440
+ this.broadcastSimAssignments();
13441
+ this.broadcastSimClientStates();
13442
+ }
13431
13443
  if (role === "sim") {
13432
13444
  if (sim) {
13433
13445
  sim.lastSeenAt = Date.now();
@@ -18852,6 +18864,142 @@ module.exports = __toCommonJS(registry_exports);
18852
18864
  var fs10 = __toESM(require("fs"), 1);
18853
18865
  var path10 = __toESM(require("path"), 1);
18854
18866
 
18867
+ // ../../scripts/lib/reap-browser.ts
18868
+ var import_node_child_process = require("node:child_process");
18869
+ function rootChromePid(b) {
18870
+ const w = b;
18871
+ if (w && typeof w.process === "function") {
18872
+ try {
18873
+ const p = w.process();
18874
+ if (p && typeof p.pid === "number" && p.pid > 0) return p.pid;
18875
+ } catch {
18876
+ }
18877
+ }
18878
+ if (w && typeof w.browser === "function") {
18879
+ try {
18880
+ const child = w.browser();
18881
+ if (child) return rootChromePid(child);
18882
+ } catch {
18883
+ }
18884
+ }
18885
+ return null;
18886
+ }
18887
+ function killTree(pid) {
18888
+ let kids = [];
18889
+ try {
18890
+ kids = (0, import_node_child_process.execSync)(`pgrep -P ${pid} || true`).toString().split("\n").filter(Boolean);
18891
+ } catch {
18892
+ }
18893
+ for (const k of kids) killTree(Number(k));
18894
+ try {
18895
+ process.kill(pid, "SIGKILL");
18896
+ } catch {
18897
+ }
18898
+ }
18899
+ var reapPids = /* @__PURE__ */ new Set();
18900
+ var installed = false;
18901
+ function installReaper() {
18902
+ if (installed) return;
18903
+ installed = true;
18904
+ const reap = () => {
18905
+ for (const pid of reapPids) killTree(pid);
18906
+ };
18907
+ process.on("SIGTERM", () => {
18908
+ reap();
18909
+ process.exit(0);
18910
+ });
18911
+ process.on("SIGINT", () => {
18912
+ reap();
18913
+ process.exit(0);
18914
+ });
18915
+ process.on("exit", reap);
18916
+ }
18917
+ async function launchReapedScoped(launch) {
18918
+ const browser = await launch();
18919
+ const root = rootChromePid(browser);
18920
+ const mine = /* @__PURE__ */ new Set();
18921
+ if (root != null) {
18922
+ mine.add(root);
18923
+ reapPids.add(root);
18924
+ installReaper();
18925
+ }
18926
+ const evented = browser;
18927
+ if (typeof evented.on === "function") {
18928
+ evented.on("disconnected", () => {
18929
+ for (const pid of mine) reapPids.delete(pid);
18930
+ });
18931
+ }
18932
+ const reapNow = () => {
18933
+ for (const pid of mine) {
18934
+ killTree(pid);
18935
+ reapPids.delete(pid);
18936
+ }
18937
+ mine.clear();
18938
+ };
18939
+ return { browser, reapNow };
18940
+ }
18941
+ async function launchReaped(launch) {
18942
+ const { browser } = await launchReapedScoped(launch);
18943
+ return browser;
18944
+ }
18945
+ var gpuChromeMissing = false;
18946
+ function gpuChromeArgs() {
18947
+ const angle = process.platform === "darwin" ? "metal" : process.platform === "linux" ? "vulkan" : "default";
18948
+ return [
18949
+ `--use-angle=${angle}`,
18950
+ "--enable-gpu",
18951
+ "--enable-gpu-rasterization",
18952
+ "--enable-zero-copy",
18953
+ "--ignore-gpu-blocklist"
18954
+ ];
18955
+ }
18956
+ function gpuChromeLaunchOptions(opts = {}) {
18957
+ const callerArgs = Array.isArray(opts.args) ? opts.args : [];
18958
+ const callerIgnored = Array.isArray(opts.ignoreDefaultArgs) ? opts.ignoreDefaultArgs : [];
18959
+ return {
18960
+ ...opts,
18961
+ channel: "chrome",
18962
+ args: [...gpuChromeArgs(), ...callerArgs],
18963
+ ignoreDefaultArgs: [...callerIgnored, "--enable-unsafe-swiftshader"]
18964
+ };
18965
+ }
18966
+ function preferGpuChrome(launch, opts) {
18967
+ return async () => {
18968
+ const allowSoftwareFallback = process.env.CI === "true" || process.env.CI === "1" || process.env.GITHUB_ACTIONS === "true";
18969
+ if (!gpuChromeMissing) {
18970
+ try {
18971
+ const callerArgs = Array.isArray(opts.args) ? opts.args : [];
18972
+ if (!allowSoftwareFallback && callerArgs.some(
18973
+ (arg) => arg === "--enable-unsafe-swiftshader" || /^--use-angle=(?:swiftshader|swiftshader-webgl)$/i.test(String(arg))
18974
+ )) {
18975
+ throw new Error("[reap-browser] refused local SwiftShader launch arguments");
18976
+ }
18977
+ return await launch(gpuChromeLaunchOptions(opts));
18978
+ } catch (err) {
18979
+ const msg = err instanceof Error ? err.message : String(err);
18980
+ const missing = /not found at|not installed|Chromium distribution|Executable doesn't exist|No such file/i.test(
18981
+ msg
18982
+ );
18983
+ if (!missing) throw err;
18984
+ if (!allowSoftwareFallback) {
18985
+ throw new Error(
18986
+ "[reap-browser] system Chrome is required for local GPU browser work; bundled Chromium/SwiftShader fallback is disabled. Install Chrome or run `npx playwright install chrome`.",
18987
+ { cause: err }
18988
+ );
18989
+ }
18990
+ gpuChromeMissing = true;
18991
+ console.warn(
18992
+ "[reap-browser] CI system Chrome not found, falling back to bundled Chromium software rendering."
18993
+ );
18994
+ }
18995
+ }
18996
+ return launch(opts);
18997
+ };
18998
+ }
18999
+ async function launchReapedChrome(launch, opts = {}) {
19000
+ return launchReaped(preferGpuChrome(launch, opts));
19001
+ }
19002
+
18855
19003
  // src/skills/builtin/a11y-review.ts
18856
19004
  var skill = {
18857
19005
  name: "a11y-review",
@@ -18870,7 +19018,9 @@ var skill = {
18870
19018
  const { chromium } = await import("playwright");
18871
19019
  const path11 = await import("path");
18872
19020
  const fs11 = await import("fs");
18873
- const browser = await chromium.launch({ channel: "chrome", headless: true });
19021
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
19022
+ headless: true
19023
+ });
18874
19024
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
18875
19025
  try {
18876
19026
  await page.goto(context.url, { waitUntil: "networkidle" });
@@ -19148,7 +19298,9 @@ var skill4 = {
19148
19298
  const { chromium } = await import("playwright");
19149
19299
  const path11 = await import("path");
19150
19300
  const fs11 = await import("fs");
19151
- const browser = await chromium.launch({ channel: "chrome", headless: true });
19301
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
19302
+ headless: true
19303
+ });
19152
19304
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
19153
19305
  try {
19154
19306
  await page.goto(context.url, { waitUntil: "networkidle" });
@@ -19207,7 +19359,9 @@ var skill5 = {
19207
19359
  const { chromium } = await import("playwright");
19208
19360
  const path11 = await import("path");
19209
19361
  const fs11 = await import("fs");
19210
- const browser = await chromium.launch({ channel: "chrome", headless: true });
19362
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
19363
+ headless: true
19364
+ });
19211
19365
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
19212
19366
  try {
19213
19367
  await page.goto(context.url, { waitUntil: "networkidle" });
@@ -19255,7 +19409,9 @@ var skill6 = {
19255
19409
  const { chromium } = await import("playwright");
19256
19410
  const path11 = await import("path");
19257
19411
  const fs11 = await import("fs");
19258
- const browser = await chromium.launch({ channel: "chrome", headless: true });
19412
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
19413
+ headless: true
19414
+ });
19259
19415
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
19260
19416
  try {
19261
19417
  await page.goto(context.url, { waitUntil: "networkidle" });
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.220 | (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.218",
3
+ "version": "0.1.220",
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",
@@ -582,7 +582,7 @@ export class SootSimBridgeHost {
582
582
  if (!this.wss) return
583
583
  this.wss.on('connection', (ws, req) => {
584
584
  const origin = req.headers.origin
585
- const role: 'sim' | 'cli' = origin ? 'sim' : 'cli'
585
+ let role: 'sim' | 'cli' = origin ? 'sim' : 'cli'
586
586
  let sim: BridgeSimConnection | null = null
587
587
 
588
588
  // ws emits 'error' for late peer-side socket faults (write EIO after
@@ -706,6 +706,26 @@ export class SootSimBridgeHost {
706
706
  return
707
707
  }
708
708
 
709
+ // Browsers always send an Origin header, but the IDE needs a second,
710
+ // short-lived CLI-role socket to route typed app_* calls to an
711
+ // sb-dev-owned external runtime driver. `bridge:hello` is already the
712
+ // CLI handshake, so let it correct the provisional Origin-based role
713
+ // before this socket has registered a page. This reuses the existing
714
+ // daemon transport and call envelope; it does not add a second routing
715
+ // surface or let a registered sim switch roles mid-connection.
716
+ if (role === 'sim' && msg.type === 'bridge:hello' && sim && !sim.url) {
717
+ const provisionalId = sim.id
718
+ this.sims.delete(provisionalId)
719
+ if (this.primarySimId === provisionalId) {
720
+ this.primarySimId = this.getOpenSim()?.id ?? null
721
+ }
722
+ sim = null
723
+ role = 'cli'
724
+ this.cliIdentityKeyBySocket.set(ws, `ws-${this.nextCliFallbackId++}`)
725
+ this.broadcastSimAssignments()
726
+ this.broadcastSimClientStates()
727
+ }
728
+
709
729
  if (role === 'sim') {
710
730
  if (sim) {
711
731
  sim.lastSeenAt = Date.now()
@@ -1,5 +1,6 @@
1
1
  // built-in skill: accessibility audit
2
2
 
3
+ import { launchReapedChrome } from '../../../../../scripts/lib/reap-browser'
3
4
  import type { SootSimSkill } from '../types'
4
5
 
5
6
  export const skill: SootSimSkill = {
@@ -23,7 +24,9 @@ export const skill: SootSimSkill = {
23
24
  // sootsim renders CanvasKit — require GPU-backed Chrome (Metal). the
24
25
  // bundled swiftshader shell software-renders the canvas and pegs every
25
26
  // core; never use it for sootsim.
26
- const browser = await chromium.launch({ channel: 'chrome', headless: true })
27
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
28
+ headless: true,
29
+ })
27
30
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } })
28
31
 
29
32
  try {
@@ -1,5 +1,6 @@
1
1
  // built-in skill: performance profiling
2
2
 
3
+ import { launchReapedChrome } from '../../../../../scripts/lib/reap-browser'
3
4
  import type { SootSimSkill } from '../types'
4
5
 
5
6
  interface OverlayProfile {
@@ -36,7 +37,9 @@ export const skill: SootSimSkill = {
36
37
  // sootsim renders CanvasKit — require GPU-backed Chrome (Metal). the
37
38
  // bundled swiftshader shell software-renders the canvas and pegs every
38
39
  // core; never use it for sootsim.
39
- const browser = await chromium.launch({ channel: 'chrome', headless: true })
40
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
41
+ headless: true,
42
+ })
40
43
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } })
41
44
 
42
45
  try {
@@ -1,5 +1,6 @@
1
1
  // built-in skill: capture all screens in light/dark mode
2
2
 
3
+ import { launchReapedChrome } from '../../../../../scripts/lib/reap-browser'
3
4
  import type { SootSimSkill } from '../types'
4
5
 
5
6
  export const skill: SootSimSkill = {
@@ -24,7 +25,9 @@ export const skill: SootSimSkill = {
24
25
  // sootsim renders CanvasKit — require GPU-backed Chrome (Metal). the
25
26
  // bundled swiftshader shell software-renders the canvas and pegs every
26
27
  // core; never use it for sootsim.
27
- const browser = await chromium.launch({ channel: 'chrome', headless: true })
28
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
29
+ headless: true,
30
+ })
28
31
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } })
29
32
 
30
33
  try {
@@ -1,5 +1,6 @@
1
1
  // built-in skill: visual diff against baselines
2
2
 
3
+ import { launchReapedChrome } from '../../../../../scripts/lib/reap-browser'
3
4
  import type { SootSimSkill } from '../types'
4
5
 
5
6
  export const skill: SootSimSkill = {
@@ -32,7 +33,9 @@ export const skill: SootSimSkill = {
32
33
  // sootsim renders CanvasKit — require GPU-backed Chrome (Metal). the
33
34
  // bundled swiftshader shell software-renders the canvas and pegs every
34
35
  // core; never use it for sootsim.
35
- const browser = await chromium.launch({ channel: 'chrome', headless: true })
36
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
37
+ headless: true,
38
+ })
36
39
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } })
37
40
 
38
41
  try {
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c,d}from"./chunk-TGXLBFTC.js";import"./chunk-EEUNNW2P.js";export{d as BETA_ASK_HEADLINE,b as BETA_LABEL,c as BETA_TAGLINE,a as IS_BETA};
@@ -1 +0,0 @@
1
- /*! sootsim v0.1.218 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */