sootsim 0.1.217 → 0.1.219

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-4FX2PQLB.js → agent-ZV6ME4EG.js} +2 -2
  5. package/dist-cli/chunks/{agent-wrapper-KIQTUCYG.js → agent-wrapper-EGFEAPFH.js} +2 -2
  6. package/dist-cli/chunks/{app-fonts-7XJS63Y2.js → app-fonts-ZWVEYPCN.js} +2 -2
  7. package/dist-cli/chunks/{assert-VQMDKAVI.js → assert-SC3W6UNR.js} +2 -2
  8. package/dist-cli/chunks/{auth-6JIMQLVG.js → auth-7OTPNXUI.js} +2 -2
  9. package/dist-cli/chunks/beta-QPKHTN3A.js +2 -0
  10. package/dist-cli/chunks/{camera-BCXQMAB3.js → camera-RQGNYESB.js} +2 -2
  11. package/dist-cli/chunks/{chunk-SBLVM6KT.js → chunk-2CCJGEVS.js} +2 -2
  12. package/dist-cli/chunks/{chunk-5WGUBDNY.js → chunk-2DOBRWPU.js} +3 -3
  13. package/dist-cli/chunks/{chunk-P2FPQYLI.js → chunk-2U4CK5R5.js} +2 -2
  14. package/dist-cli/chunks/{chunk-Z6H5YGVP.js → chunk-3B5UXJ3Y.js} +1 -1
  15. package/dist-cli/chunks/{chunk-II5GPTCI.js → chunk-3GQ2VZT3.js} +2 -2
  16. package/dist-cli/chunks/{chunk-IRCQILE3.js → chunk-3PMTZACY.js} +2 -2
  17. package/dist-cli/chunks/{chunk-5PMHRL26.js → chunk-3QEIIJ4U.js} +2 -2
  18. package/dist-cli/chunks/{chunk-XGOENFDF.js → chunk-4KBHOKFR.js} +4 -4
  19. package/dist-cli/chunks/{chunk-KDMMOZWO.js → chunk-7EMJ67H5.js} +9 -9
  20. package/dist-cli/chunks/{chunk-CGQGD4YT.js → chunk-7RSH52LR.js} +1 -1
  21. package/dist-cli/chunks/{chunk-PH6F62XI.js → chunk-7VZLWO2D.js} +2 -2
  22. package/dist-cli/chunks/{chunk-C3L2JWQF.js → chunk-AWM244TZ.js} +3 -3
  23. package/dist-cli/chunks/{chunk-43HOXICB.js → chunk-BTLNZG23.js} +1 -1
  24. package/dist-cli/chunks/{chunk-DPR6E3DA.js → chunk-C5LRFEF4.js} +1 -1
  25. package/dist-cli/chunks/{chunk-KPQIXJ6P.js → chunk-EMWJQRT7.js} +2 -2
  26. package/dist-cli/chunks/{chunk-PNN5RIHU.js → chunk-FGIGSM4Z.js} +2 -2
  27. package/dist-cli/chunks/{chunk-72ACLZTK.js → chunk-FJPEIFZW.js} +1 -1
  28. package/dist-cli/chunks/{chunk-5LY3QGYK.js → chunk-G26OO66G.js} +1 -1
  29. package/dist-cli/chunks/{chunk-VFM2GCJK.js → chunk-GXIL7GMS.js} +1 -1
  30. package/dist-cli/chunks/{chunk-PNEWTGQD.js → chunk-I6SPORCZ.js} +1 -1
  31. package/dist-cli/chunks/{chunk-YIEZXEFD.js → chunk-ITYDRFAM.js} +3 -3
  32. package/dist-cli/chunks/chunk-J3WU2XCQ.js +1 -0
  33. package/dist-cli/chunks/{chunk-ZP7IKLL5.js → chunk-JEMQ2DRI.js} +2 -2
  34. package/dist-cli/chunks/{chunk-5MRHVSLH.js → chunk-JT5JOWHK.js} +1 -1
  35. package/dist-cli/chunks/{chunk-WOVVMHGW.js → chunk-JVJNG6BQ.js} +2 -2
  36. package/dist-cli/chunks/{chunk-DLGYFFRD.js → chunk-JYU7BIGJ.js} +2 -2
  37. package/dist-cli/chunks/{chunk-V33VVORZ.js → chunk-KLTHI6RE.js} +2 -2
  38. package/dist-cli/chunks/{chunk-WSHEWWAP.js → chunk-LNNBPSAL.js} +2 -2
  39. package/dist-cli/chunks/{chunk-2QZEYMIG.js → chunk-LUWFFYQL.js} +2 -2
  40. package/dist-cli/chunks/chunk-NVDHSK33.js +119 -0
  41. package/dist-cli/chunks/{chunk-HKQG2TQP.js → chunk-PMERG7PS.js} +1 -1
  42. package/dist-cli/chunks/{chunk-2MCDMCYQ.js → chunk-PYIMY6VO.js} +1 -1
  43. package/dist-cli/chunks/{chunk-F3OVNA6L.js → chunk-QH5KCAPX.js} +1 -1
  44. package/dist-cli/chunks/{chunk-JVV5UWFI.js → chunk-RCHJJ5GW.js} +1 -1
  45. package/dist-cli/chunks/{chunk-EDF3RMTS.js → chunk-UEA4JYEY.js} +2 -2
  46. package/dist-cli/chunks/{chunk-FHZ72TK4.js → chunk-V4VPUZVL.js} +91 -14
  47. package/dist-cli/chunks/{chunk-OKKXVF4E.js → chunk-WTWTKL3R.js} +6 -6
  48. package/dist-cli/chunks/chunk-Y6Y7QQLA.js +1 -0
  49. package/dist-cli/chunks/{chunk-FS73CB2S.js → chunk-Y7GPDSA2.js} +1 -1
  50. package/dist-cli/chunks/{chunk-Z5DRCU5R.js → chunk-ZGTMYSKV.js} +2 -2
  51. package/dist-cli/chunks/{chunk-5HXI2BXE.js → chunk-ZHMKPUDR.js} +2 -2
  52. package/dist-cli/chunks/{chunk-XNLHQI4J.js → chunk-ZNDD2KOF.js} +1 -1
  53. package/dist-cli/chunks/{chunk-7GGP6CHB.js → chunk-ZXFWW4MR.js} +1 -1
  54. package/dist-cli/chunks/cli-version-ZUBCW7QA.js +2 -0
  55. package/dist-cli/chunks/{compat-VMLCACM3.js → compat-WICAPL25.js} +3 -3
  56. package/dist-cli/chunks/{config-PTMQDYOZ.js → config-MGQCNMDQ.js} +2 -2
  57. package/dist-cli/chunks/{control-SHITPCIX.js → control-GW7OQZ2R.js} +2 -2
  58. package/dist-cli/chunks/daemon-2A2YTRXY.js +2 -0
  59. package/dist-cli/chunks/{debug-MJEQ2R54.js → debug-54HQV7MN.js} +3 -3
  60. package/dist-cli/chunks/{desktop-Z4LOP37S.js → desktop-5FWYDFK2.js} +3 -3
  61. package/dist-cli/chunks/{detox-VGPLTJYZ.js → detox-75KJXI7K.js} +2 -2
  62. package/dist-cli/chunks/{device-H5CH3XAB.js → device-VRR2CFKN.js} +2 -2
  63. package/dist-cli/chunks/{diagnose-AIQGCXUP.js → diagnose-DS623ULB.js} +2 -2
  64. package/dist-cli/chunks/drivers-6QFTJGK6.js +2 -0
  65. package/dist-cli/chunks/{film-P66JPUHW.js → film-6I22LQ4E.js} +3 -3
  66. package/dist-cli/chunks/flow-4RXVOUUF.js +2 -0
  67. package/dist-cli/chunks/help-IXPZBF5H.js +2 -0
  68. package/dist-cli/chunks/{home-paths-WMQMWUNA.js → home-paths-D7QIYKT2.js} +2 -2
  69. package/dist-cli/chunks/inspect-SU5K5IER.js +2 -0
  70. package/dist-cli/chunks/install-desktop-PN4SCIMA.js +2 -0
  71. package/dist-cli/chunks/{login-IAHY7E6Y.js → login-ETKHVL7Z.js} +4 -4
  72. package/dist-cli/chunks/{logout-2YEUFJAD.js → logout-FLW7LPE3.js} +2 -2
  73. package/dist-cli/chunks/{maestro-BSD43NA3.js → maestro-D3MAAOMX.js} +3 -3
  74. package/dist-cli/chunks/{maestro-generate-QU74GL7P.js → maestro-generate-73HS4LME.js} +3 -3
  75. package/dist-cli/chunks/{mode-UMJMUA3Y.js → mode-SOXJRJIN.js} +2 -2
  76. package/dist-cli/chunks/optional-demo-registry-N2J3NEGC.js +2 -0
  77. package/dist-cli/chunks/{perf-XMNXZFDY.js → perf-YAKR4GMN.js} +2 -2
  78. package/dist-cli/chunks/{record-UCDYKK5M.js → record-HWKSSN3E.js} +3 -3
  79. package/dist-cli/chunks/runtime-ZUWXQ46T.js +2 -0
  80. package/dist-cli/chunks/screenshot-command-UNDC4C2R.js +151 -0
  81. package/dist-cli/chunks/screenshots-capture-QZSUIT4R.js +41 -0
  82. package/dist-cli/chunks/{serve-L4XOZE3V.js → serve-D66T2PP3.js} +2 -2
  83. package/dist-cli/chunks/{setup-O3TUZ5JW.js → setup-FML4JBOA.js} +9 -9
  84. package/dist-cli/chunks/{skills-P4KO6RFE.js → skills-O2KIPSJ6.js} +2 -2
  85. package/dist-cli/chunks/{storage-RTPEVRAI.js → storage-T7MGNCI7.js} +2 -2
  86. package/dist-cli/chunks/store-WTRJT3P5.js +2 -0
  87. package/dist-cli/chunks/telemetry-7HV5GWEK.js +2 -0
  88. package/dist-cli/chunks/{timeline-64CDTB5K.js → timeline-OQEJCRNZ.js} +2 -2
  89. package/dist-cli/chunks/upgrade-TL36WOFS.js +4 -0
  90. package/dist-cli/chunks/upload-7CIEKZM6.js +2 -0
  91. package/dist-cli/chunks/{version-A5YSPPCX.js → version-XG3TA6TB.js} +2 -2
  92. package/dist-cli/chunks/web-LVUK3CHP.js +2 -0
  93. package/dist-cli/chunks/{what-happened-Y3MVLKPF.js → what-happened-SASUKQEF.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 +1 -1
  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 +176 -30
  125. package/dist-lib/vite.cjs +1 -1
  126. package/package.json +1 -1
  127. package/src/skills/builtin/a11y-review.ts +4 -1
  128. package/src/skills/builtin/perf-profile.ts +4 -1
  129. package/src/skills/builtin/screenshot-all.ts +4 -1
  130. package/src/skills/builtin/visual-diff.ts +4 -1
  131. package/dist-cli/chunks/beta-N2ZUIDGA.js +0 -2
  132. package/dist-cli/chunks/chunk-GLAMORG7.js +0 -1
  133. package/dist-cli/chunks/chunk-IQUBZ6UH.js +0 -119
  134. package/dist-cli/chunks/chunk-S3NTQ523.js +0 -1
  135. package/dist-cli/chunks/cli-version-57GES5K7.js +0 -2
  136. package/dist-cli/chunks/daemon-KHJZASBC.js +0 -2
  137. package/dist-cli/chunks/drivers-LRTSTFSZ.js +0 -2
  138. package/dist-cli/chunks/flow-JETK5JHP.js +0 -2
  139. package/dist-cli/chunks/help-XX557QGO.js +0 -2
  140. package/dist-cli/chunks/inspect-JTBKTX2E.js +0 -2
  141. package/dist-cli/chunks/install-desktop-OFWYZIJ2.js +0 -2
  142. package/dist-cli/chunks/optional-demo-registry-MS2YBMHN.js +0 -2
  143. package/dist-cli/chunks/runtime-VNQTSGVX.js +0 -2
  144. package/dist-cli/chunks/screenshot-command-UZOLNSJN.js +0 -151
  145. package/dist-cli/chunks/screenshots-capture-NOWHE4AB.js +0 -41
  146. package/dist-cli/chunks/store-P23ZWVHH.js +0 -2
  147. package/dist-cli/chunks/telemetry-UFGF53JT.js +0 -2
  148. package/dist-cli/chunks/upgrade-OLGZ7K6Y.js +0 -4
  149. package/dist-cli/chunks/upload-GQYWQIIG.js +0 -2
  150. package/dist-cli/chunks/web-U6OTYNPM.js +0 -2
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.217 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.219 | (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
  },
@@ -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.9,
272
+ note: "core RN\u2194UI thread bridging, runtime-kind guards, UI-runtime-id execution, shareable/synchronizable guards, custom serializable registration, and feature flag readers use the SAB-backed tenant\u2194shell runtime.",
273
+ working: "runOnJS, runOnUI/Sync/Async, scheduleOnRN/UI, UI-runtime runOnRuntime/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: "isolated named runtimes are not implemented: createWorkletRuntime, Worklets.createRuntime/createContext, and named run/schedule calls throw explicitly instead of returning inert handles; 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
  },
@@ -1391,9 +1391,10 @@ var init_registry = __esm({
1391
1391
  versions: [
1392
1392
  {
1393
1393
  range: ">=6.0.0",
1394
- coverage: 1,
1395
- note: "HTML date/time/datetime-local input; Android imperative API stubbed",
1396
- working: "DateTimePicker, DateTimePickerAndroid (open/dismiss), minimumDate, maximumDate, minuteInterval, all IOSMode/AndroidMode values, DateTimePickerMode, DateTimePickerDisplay, AndroidEvent constants"
1394
+ coverage: 0.9,
1395
+ note: "engine UIDatePicker wheels back both paths: the JS-surface stub renders them directly, and bundles running the real package JS resolve codegenNativeComponent('RNDateTimePicker') to the same wheel via a registered host view. onChange delivers upstream's (event, date) with { timestamp, utcOffset }.",
1396
+ working: "DateTimePicker (value, mode date/time/datetime, onChange, minimumDate, maximumDate, minuteInterval, locale, timeZoneOffsetInMinutes, textColor, themeVariant, disabled), DateTimePickerMode, DateTimePickerDisplay, AndroidEvent constants, DateTimePickerAndroid (open/dismiss shape)",
1397
+ missing: "displayIOS 'default'/'compact'/'inline' calendar styles (all render as wheels), countdown mode renders the time wheel, timeZoneName (use timeZoneOffsetInMinutes), accentColor, onPickerDismiss"
1397
1398
  }
1398
1399
  ]
1399
1400
  },
@@ -1416,9 +1417,10 @@ var init_registry = __esm({
1416
1417
  versions: [
1417
1418
  {
1418
1419
  range: ">=2.0.0",
1419
- coverage: 1,
1420
- note: "HTML select element with full Picker API including Picker.Item, modes, focus/blur",
1421
- working: "Picker, PickerIOS, Picker.Item, selectedValue, onValueChange, enabled, mode, prompt, dropdownIconColor, MODE_DIALOG, MODE_DROPDOWN"
1420
+ coverage: 0.9,
1421
+ note: "engine UIPickerView wheel (selection capsule, edge fade, drag/fling/snap) backing the Picker/PickerIOS surface; Picker.Item is data-only like upstream iOS. itemStyle color/fontSize honored, per-item color via Picker.Item color.",
1422
+ working: "Picker, PickerIOS, Picker.Item (label, value, color), selectedValue, onValueChange(value, index), enabled, itemStyle color/fontSize, MODE_DIALOG, MODE_DROPDOWN constants",
1423
+ missing: "android dialog/dropdown presentation (mode/prompt/dropdownIconColor render as the iOS wheel), focus()/blur() imperative handle, onFocus/onBlur"
1422
1424
  }
1423
1425
  ]
1424
1426
  },
@@ -1660,10 +1662,10 @@ var init_registry = __esm({
1660
1662
  versions: [
1661
1663
  {
1662
1664
  range: ">=5.0.0",
1663
- coverage: 0.93,
1664
- note: "real HTML date / time / datetime-local input backing the picker, plus a real overlay <dialog> for modal/open mode. all core date-flow events (onDateChange / onConfirm / onCancel) wire through native input events. native iOS wheel-spin UX is the documented absent shape.",
1665
- working: "DatePicker, date, onDateChange, onConfirm, onCancel, mode (date/time/datetime), minimumDate, maximumDate, minuteInterval, modal, open, DatePickerModal",
1666
- missing: "native iOS wheel-spin visual (browsers default to date-input chrome), full locale formatting (relies on toLocaleString defaults), themed light/dark styling tokens"
1665
+ coverage: 0.9,
1666
+ note: "native-seam only \u2014 the real package JS runs from the bundle; requireNativeComponent('RNDatePicker') resolves to the engine's UIDatePickerStyleWheels implementation (canvas wheel columns with drag/fling/snap physics, selection capsule, edge fade, locale-ordered date parts via Intl, light/dark/auto theme). onChange emits the upstream { timestamp: ms } contract on wheel settle.",
1667
+ working: "DatePicker (inline), date, onDateChange, mode (date/time/datetime), locale (month names, y/m/d column order, 12/24h cycle, day-period labels), minimumDate, maximumDate (settle-clamp bounce), minuteInterval, timeZoneOffsetInMinutes, textColor, theme",
1668
+ missing: "modal/open mode (NativeModules.RNDatePicker openPicker seam is a no-op; onConfirm/onCancel never fire), wheel wrap-around for month/day columns, cylindrical row compression (edge fade only), datetime day wheel spans min/max or \xB12 years instead of the UIKit range"
1667
1669
  }
1668
1670
  ]
1669
1671
  },
@@ -11609,7 +11611,7 @@ function mkfifoSync(p) {
11609
11611
  import_node_fs4.default.unlinkSync(p);
11610
11612
  }
11611
11613
  }
11612
- 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]);
11613
11615
  if (result.status !== 0) {
11614
11616
  throw new Error(
11615
11617
  `mkfifo(${p}) failed: ${result.stderr?.toString().trim() || "unknown error"}`
@@ -11677,7 +11679,7 @@ async function startSession(opts) {
11677
11679
  if (claudeSessionUuid) {
11678
11680
  wrapperArgs.push("--claude-session-uuid", claudeSessionUuid);
11679
11681
  }
11680
- const child = (0, import_node_child_process.spawn)(cmd, wrapperArgs, {
11682
+ const child = (0, import_node_child_process2.spawn)(cmd, wrapperArgs, {
11681
11683
  detached: true,
11682
11684
  stdio: "ignore",
11683
11685
  env: {
@@ -11825,11 +11827,11 @@ async function waitForFirstEvent(fifo, predicate, timeoutMs) {
11825
11827
  import_node_fs4.default.closeSync(fd);
11826
11828
  }
11827
11829
  }
11828
- 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;
11829
11831
  var init_agent_sessions = __esm({
11830
11832
  "src/agent-sessions.ts"() {
11831
11833
  "use strict";
11832
- import_node_child_process = require("node:child_process");
11834
+ import_node_child_process2 = require("node:child_process");
11833
11835
  import_node_crypto2 = require("node:crypto");
11834
11836
  import_node_fs4 = __toESM(require("node:fs"), 1);
11835
11837
  import_node_path3 = __toESM(require("node:path"), 1);
@@ -11890,7 +11892,7 @@ async function sendPromptToAgentbusSession(input) {
11890
11892
  const command = resolveAgentbusCommand(input.command);
11891
11893
  const timeoutMs = input.timeoutMs ?? 15e3;
11892
11894
  await new Promise((resolve5, reject) => {
11893
- 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], {
11894
11896
  stdio: ["ignore", "ignore", "pipe"],
11895
11897
  env: process.env
11896
11898
  });
@@ -11925,11 +11927,11 @@ async function sendPromptToAgentbusSession(input) {
11925
11927
  });
11926
11928
  });
11927
11929
  }
11928
- 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;
11929
11931
  var init_agentbus_prompt = __esm({
11930
11932
  "src/agentbus-prompt.ts"() {
11931
11933
  "use strict";
11932
- import_node_child_process2 = require("node:child_process");
11934
+ import_node_child_process3 = require("node:child_process");
11933
11935
  import_node_fs5 = __toESM(require("node:fs"), 1);
11934
11936
  import_node_os2 = __toESM(require("node:os"), 1);
11935
11937
  import_node_path4 = __toESM(require("node:path"), 1);
@@ -13383,8 +13385,8 @@ var init_bridge_host = __esm({
13383
13385
  }
13384
13386
  if (msg.type === "runtime:use") {
13385
13387
  const version = typeof msg.version === "string" ? msg.version : "";
13386
- const installed = listInstalledRuntimes();
13387
- if (!installed.includes(version)) {
13388
+ const installed2 = listInstalledRuntimes();
13389
+ if (!installed2.includes(version)) {
13388
13390
  try {
13389
13391
  ws.send(
13390
13392
  JSON.stringify({
@@ -18850,6 +18852,142 @@ module.exports = __toCommonJS(registry_exports);
18850
18852
  var fs10 = __toESM(require("fs"), 1);
18851
18853
  var path10 = __toESM(require("path"), 1);
18852
18854
 
18855
+ // ../../scripts/lib/reap-browser.ts
18856
+ var import_node_child_process = require("node:child_process");
18857
+ function rootChromePid(b) {
18858
+ const w = b;
18859
+ if (w && typeof w.process === "function") {
18860
+ try {
18861
+ const p = w.process();
18862
+ if (p && typeof p.pid === "number" && p.pid > 0) return p.pid;
18863
+ } catch {
18864
+ }
18865
+ }
18866
+ if (w && typeof w.browser === "function") {
18867
+ try {
18868
+ const child = w.browser();
18869
+ if (child) return rootChromePid(child);
18870
+ } catch {
18871
+ }
18872
+ }
18873
+ return null;
18874
+ }
18875
+ function killTree(pid) {
18876
+ let kids = [];
18877
+ try {
18878
+ kids = (0, import_node_child_process.execSync)(`pgrep -P ${pid} || true`).toString().split("\n").filter(Boolean);
18879
+ } catch {
18880
+ }
18881
+ for (const k of kids) killTree(Number(k));
18882
+ try {
18883
+ process.kill(pid, "SIGKILL");
18884
+ } catch {
18885
+ }
18886
+ }
18887
+ var reapPids = /* @__PURE__ */ new Set();
18888
+ var installed = false;
18889
+ function installReaper() {
18890
+ if (installed) return;
18891
+ installed = true;
18892
+ const reap = () => {
18893
+ for (const pid of reapPids) killTree(pid);
18894
+ };
18895
+ process.on("SIGTERM", () => {
18896
+ reap();
18897
+ process.exit(0);
18898
+ });
18899
+ process.on("SIGINT", () => {
18900
+ reap();
18901
+ process.exit(0);
18902
+ });
18903
+ process.on("exit", reap);
18904
+ }
18905
+ async function launchReapedScoped(launch) {
18906
+ const browser = await launch();
18907
+ const root = rootChromePid(browser);
18908
+ const mine = /* @__PURE__ */ new Set();
18909
+ if (root != null) {
18910
+ mine.add(root);
18911
+ reapPids.add(root);
18912
+ installReaper();
18913
+ }
18914
+ const evented = browser;
18915
+ if (typeof evented.on === "function") {
18916
+ evented.on("disconnected", () => {
18917
+ for (const pid of mine) reapPids.delete(pid);
18918
+ });
18919
+ }
18920
+ const reapNow = () => {
18921
+ for (const pid of mine) {
18922
+ killTree(pid);
18923
+ reapPids.delete(pid);
18924
+ }
18925
+ mine.clear();
18926
+ };
18927
+ return { browser, reapNow };
18928
+ }
18929
+ async function launchReaped(launch) {
18930
+ const { browser } = await launchReapedScoped(launch);
18931
+ return browser;
18932
+ }
18933
+ var gpuChromeMissing = false;
18934
+ function gpuChromeArgs() {
18935
+ const angle = process.platform === "darwin" ? "metal" : process.platform === "linux" ? "vulkan" : "default";
18936
+ return [
18937
+ `--use-angle=${angle}`,
18938
+ "--enable-gpu",
18939
+ "--enable-gpu-rasterization",
18940
+ "--enable-zero-copy",
18941
+ "--ignore-gpu-blocklist"
18942
+ ];
18943
+ }
18944
+ function gpuChromeLaunchOptions(opts = {}) {
18945
+ const callerArgs = Array.isArray(opts.args) ? opts.args : [];
18946
+ const callerIgnored = Array.isArray(opts.ignoreDefaultArgs) ? opts.ignoreDefaultArgs : [];
18947
+ return {
18948
+ ...opts,
18949
+ channel: "chrome",
18950
+ args: [...gpuChromeArgs(), ...callerArgs],
18951
+ ignoreDefaultArgs: [...callerIgnored, "--enable-unsafe-swiftshader"]
18952
+ };
18953
+ }
18954
+ function preferGpuChrome(launch, opts) {
18955
+ return async () => {
18956
+ const allowSoftwareFallback = process.env.CI === "true" || process.env.CI === "1" || process.env.GITHUB_ACTIONS === "true";
18957
+ if (!gpuChromeMissing) {
18958
+ try {
18959
+ const callerArgs = Array.isArray(opts.args) ? opts.args : [];
18960
+ if (!allowSoftwareFallback && callerArgs.some(
18961
+ (arg) => arg === "--enable-unsafe-swiftshader" || /^--use-angle=(?:swiftshader|swiftshader-webgl)$/i.test(String(arg))
18962
+ )) {
18963
+ throw new Error("[reap-browser] refused local SwiftShader launch arguments");
18964
+ }
18965
+ return await launch(gpuChromeLaunchOptions(opts));
18966
+ } catch (err) {
18967
+ const msg = err instanceof Error ? err.message : String(err);
18968
+ const missing = /not found at|not installed|Chromium distribution|Executable doesn't exist|No such file/i.test(
18969
+ msg
18970
+ );
18971
+ if (!missing) throw err;
18972
+ if (!allowSoftwareFallback) {
18973
+ throw new Error(
18974
+ "[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`.",
18975
+ { cause: err }
18976
+ );
18977
+ }
18978
+ gpuChromeMissing = true;
18979
+ console.warn(
18980
+ "[reap-browser] CI system Chrome not found, falling back to bundled Chromium software rendering."
18981
+ );
18982
+ }
18983
+ }
18984
+ return launch(opts);
18985
+ };
18986
+ }
18987
+ async function launchReapedChrome(launch, opts = {}) {
18988
+ return launchReaped(preferGpuChrome(launch, opts));
18989
+ }
18990
+
18853
18991
  // src/skills/builtin/a11y-review.ts
18854
18992
  var skill = {
18855
18993
  name: "a11y-review",
@@ -18868,7 +19006,9 @@ var skill = {
18868
19006
  const { chromium } = await import("playwright");
18869
19007
  const path11 = await import("path");
18870
19008
  const fs11 = await import("fs");
18871
- const browser = await chromium.launch({ channel: "chrome", headless: true });
19009
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
19010
+ headless: true
19011
+ });
18872
19012
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
18873
19013
  try {
18874
19014
  await page.goto(context.url, { waitUntil: "networkidle" });
@@ -19146,7 +19286,9 @@ var skill4 = {
19146
19286
  const { chromium } = await import("playwright");
19147
19287
  const path11 = await import("path");
19148
19288
  const fs11 = await import("fs");
19149
- const browser = await chromium.launch({ channel: "chrome", headless: true });
19289
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
19290
+ headless: true
19291
+ });
19150
19292
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
19151
19293
  try {
19152
19294
  await page.goto(context.url, { waitUntil: "networkidle" });
@@ -19205,7 +19347,9 @@ var skill5 = {
19205
19347
  const { chromium } = await import("playwright");
19206
19348
  const path11 = await import("path");
19207
19349
  const fs11 = await import("fs");
19208
- const browser = await chromium.launch({ channel: "chrome", headless: true });
19350
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
19351
+ headless: true
19352
+ });
19209
19353
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
19210
19354
  try {
19211
19355
  await page.goto(context.url, { waitUntil: "networkidle" });
@@ -19253,7 +19397,9 @@ var skill6 = {
19253
19397
  const { chromium } = await import("playwright");
19254
19398
  const path11 = await import("path");
19255
19399
  const fs11 = await import("fs");
19256
- const browser = await chromium.launch({ channel: "chrome", headless: true });
19400
+ const browser = await launchReapedChrome((options) => chromium.launch(options), {
19401
+ headless: true
19402
+ });
19257
19403
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
19258
19404
  try {
19259
19405
  await page.goto(context.url, { waitUntil: "networkidle" });
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.217 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.219 | (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.217",
3
+ "version": "0.1.219",
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",
@@ -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.217 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c,d}from"./chunk-72ACLZTK.js";import"./chunk-2MCDMCYQ.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.217 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */