sootsim 0.1.214 → 0.1.216

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 (149) hide show
  1. package/detox/index.ts +30 -16
  2. package/dist-cli/bin.js +4 -4
  3. package/dist-cli/chunks/{agent-QE4ZAHV2.js → agent-RMGUE35J.js} +2 -2
  4. package/dist-cli/chunks/{agent-wrapper-E5HCJNYH.js → agent-wrapper-PNKMWDVX.js} +2 -2
  5. package/dist-cli/chunks/{app-fonts-4ADYMRQO.js → app-fonts-Z6SGSVKJ.js} +2 -2
  6. package/dist-cli/chunks/{assert-QZSX66RW.js → assert-ELIDRXY7.js} +2 -2
  7. package/dist-cli/chunks/{auth-LW224VBS.js → auth-2NJA7QI6.js} +2 -2
  8. package/dist-cli/chunks/beta-MTYUL7U7.js +2 -0
  9. package/dist-cli/chunks/{camera-MPIQ3JAA.js → camera-XICNRGGO.js} +2 -2
  10. package/dist-cli/chunks/{chunk-3CNHHY7U.js → chunk-2FNN7T63.js} +1 -1
  11. package/dist-cli/chunks/{chunk-USSUXBPG.js → chunk-4BUASWNE.js} +1 -1
  12. package/dist-cli/chunks/{chunk-I4UH6RI5.js → chunk-4XCGYTBN.js} +2 -2
  13. package/dist-cli/chunks/chunk-5LT4NR6Y.js +1 -0
  14. package/dist-cli/chunks/chunk-6KRC622O.js +1 -0
  15. package/dist-cli/chunks/{chunk-Z6X2QRA3.js → chunk-6TZMBHQ5.js} +3 -3
  16. package/dist-cli/chunks/{chunk-4RHFQCED.js → chunk-7SPHDLSB.js} +2 -2
  17. package/dist-cli/chunks/{chunk-6QMGV5H7.js → chunk-AWSL2LAA.js} +2 -2
  18. package/dist-cli/chunks/{chunk-L3CQVAWX.js → chunk-BGDEZZWT.js} +2 -2
  19. package/dist-cli/chunks/{chunk-DUGNFSB5.js → chunk-CCFLATUR.js} +2 -2
  20. package/dist-cli/chunks/{chunk-USW3U45B.js → chunk-CQSIRKJ2.js} +2 -2
  21. package/dist-cli/chunks/{chunk-KHIKG5LO.js → chunk-CRU7UL5Q.js} +1 -1
  22. package/dist-cli/chunks/{chunk-CZZZC3BU.js → chunk-CU3LQUJD.js} +2 -2
  23. package/dist-cli/chunks/chunk-DA7KPSMF.js +2 -0
  24. package/dist-cli/chunks/{chunk-SLX3HZPR.js → chunk-DRFWZ74H.js} +1 -1
  25. package/dist-cli/chunks/{chunk-XJEIT5CH.js → chunk-G6VHJWGQ.js} +1 -1
  26. package/dist-cli/chunks/{chunk-RRFWPEQ6.js → chunk-GIZDZKHC.js} +1 -1
  27. package/dist-cli/chunks/{chunk-IUTSWOUM.js → chunk-GPLW7IL5.js} +2 -2
  28. package/dist-cli/chunks/{chunk-QPZW76ZB.js → chunk-HBCEGJQH.js} +2 -2
  29. package/dist-cli/chunks/chunk-HIDDRHAN.js +99 -0
  30. package/dist-cli/chunks/chunk-HKKKZRKS.js +89 -0
  31. package/dist-cli/chunks/{chunk-DABWOLOT.js → chunk-HZCW6RRE.js} +2 -2
  32. package/dist-cli/chunks/{chunk-2344ZBLD.js → chunk-J4GDWHXE.js} +2 -2
  33. package/dist-cli/chunks/{chunk-TI2ZOHON.js → chunk-J74AW22R.js} +1 -1
  34. package/dist-cli/chunks/{chunk-6LJUMA3J.js → chunk-LWECTC6A.js} +2 -2
  35. package/dist-cli/chunks/{chunk-6EP67RW7.js → chunk-M2DYRSIS.js} +2 -2
  36. package/dist-cli/chunks/chunk-P5JY275Q.js +119 -0
  37. package/dist-cli/chunks/{chunk-XQP4TU6P.js → chunk-P735P65P.js} +93 -65
  38. package/dist-cli/chunks/{chunk-R35AOOU4.js → chunk-QNRORBZE.js} +2 -2
  39. package/dist-cli/chunks/{chunk-TX53NA5W.js → chunk-RESHDGBU.js} +1 -1
  40. package/dist-cli/chunks/{chunk-Y3T4POUK.js → chunk-S3C2S27B.js} +2 -2
  41. package/dist-cli/chunks/{chunk-AYY7JBXA.js → chunk-SBP46OOV.js} +1 -1
  42. package/dist-cli/chunks/{chunk-5LD4QHER.js → chunk-SPKRGAWR.js} +6 -6
  43. package/dist-cli/chunks/{chunk-YVIUYF5U.js → chunk-SSLFXUZQ.js} +1 -1
  44. package/dist-cli/chunks/chunk-TNPHXSMV.js +2 -0
  45. package/dist-cli/chunks/{chunk-AXXJSIT3.js → chunk-U7UICUB4.js} +2 -2
  46. package/dist-cli/chunks/{chunk-LRIZ5ACL.js → chunk-UGNYHNBN.js} +3 -3
  47. package/dist-cli/chunks/{chunk-GTRGDGRK.js → chunk-UPLXEL4D.js} +1 -1
  48. package/dist-cli/chunks/{chunk-2HCVCJB7.js → chunk-URGNAE7V.js} +31 -31
  49. package/dist-cli/chunks/{chunk-5P6QAHAI.js → chunk-VDONTXCB.js} +1 -1
  50. package/dist-cli/chunks/{chunk-L5XB3GRM.js → chunk-VSGSEQE7.js} +2 -2
  51. package/dist-cli/chunks/{chunk-BNUZWRON.js → chunk-VURHG6DO.js} +1 -1
  52. package/dist-cli/chunks/{chunk-KPRSDBWU.js → chunk-YN44PKW5.js} +1 -1
  53. package/dist-cli/chunks/cli-version-BP5GKAZ6.js +2 -0
  54. package/dist-cli/chunks/{compat-IZXTAA6Q.js → compat-MF7YZPCS.js} +3 -3
  55. package/dist-cli/chunks/{config-KV7J63HM.js → config-WJSCJ622.js} +2 -2
  56. package/dist-cli/chunks/{control-CRJA7SXC.js → control-AZFQJXJ5.js} +2 -2
  57. package/dist-cli/chunks/daemon-MU77JEAP.js +2 -0
  58. package/dist-cli/chunks/{debug-ZCPDU23K.js → debug-LIXGHFHV.js} +3 -3
  59. package/dist-cli/chunks/{desktop-HKTZX7OT.js → desktop-T7GTXHL4.js} +3 -3
  60. package/dist-cli/chunks/{detox-LNWHCNFM.js → detox-WV5FD4G6.js} +2 -2
  61. package/dist-cli/chunks/{device-AV34WOXK.js → device-GPHUF3BL.js} +2 -2
  62. package/dist-cli/chunks/{diagnose-7INR3HKD.js → diagnose-OAXHSPXW.js} +2 -2
  63. package/dist-cli/chunks/drivers-LJAA7XSZ.js +2 -0
  64. package/dist-cli/chunks/film-ZBYERRWW.js +69 -0
  65. package/dist-cli/chunks/flow-TXG46ARF.js +2 -0
  66. package/dist-cli/chunks/help-BVVLN5KL.js +2 -0
  67. package/dist-cli/chunks/{home-paths-ML5HT67C.js → home-paths-T3SY5QGR.js} +2 -2
  68. package/dist-cli/chunks/inspect-7SHQVCCL.js +2 -0
  69. package/dist-cli/chunks/install-desktop-RFGXCZRS.js +2 -0
  70. package/dist-cli/chunks/{login-IND3C7NP.js → login-QS2GVTJJ.js} +4 -4
  71. package/dist-cli/chunks/{logout-H6R4RQK7.js → logout-I752SSKU.js} +2 -2
  72. package/dist-cli/chunks/{maestro-IVTBNNF6.js → maestro-RDBKRP4O.js} +3 -3
  73. package/dist-cli/chunks/{maestro-generate-WCFBU5JM.js → maestro-generate-JOTQKAEH.js} +3 -3
  74. package/dist-cli/chunks/mode-Z4W3XXXU.js +24 -0
  75. package/dist-cli/chunks/optional-demo-registry-JTRVZB45.js +2 -0
  76. package/dist-cli/chunks/{perf-TNLPQUZI.js → perf-RXXW5GRA.js} +2 -2
  77. package/dist-cli/chunks/{record-MBJMHM23.js → record-527ZYKHE.js} +3 -3
  78. package/dist-cli/chunks/runtime-DOAHJLEK.js +2 -0
  79. package/dist-cli/chunks/{screenshot-command-Q5TFWB2R.js → screenshot-command-OBPEZJLR.js} +3 -3
  80. package/dist-cli/chunks/{screenshots-capture-AW5VYVOF.js → screenshots-capture-VC752Q3V.js} +2 -2
  81. package/dist-cli/chunks/{serve-L5XOVSCM.js → serve-NU6WWN2K.js} +2 -2
  82. package/dist-cli/chunks/{setup-TKXVNVBX.js → setup-6BJWI3PC.js} +3 -3
  83. package/dist-cli/chunks/{skills-GFZ5Z46I.js → skills-L7JPAJEZ.js} +2 -2
  84. package/dist-cli/chunks/{storage-SW3CLSLM.js → storage-XIZZSPC3.js} +2 -2
  85. package/dist-cli/chunks/store-3UAGOXD4.js +2 -0
  86. package/dist-cli/chunks/telemetry-IXCWQVEB.js +2 -0
  87. package/dist-cli/chunks/{timeline-LVV6HPFG.js → timeline-3MAGSV2V.js} +2 -2
  88. package/dist-cli/chunks/{upgrade-B22ZDON2.js → upgrade-YDHOHVYZ.js} +2 -2
  89. package/dist-cli/chunks/upload-YQVEPIO7.js +2 -0
  90. package/dist-cli/chunks/{version-G2X5AZHL.js → version-QDGDS5P2.js} +2 -2
  91. package/dist-cli/chunks/web-BK6VHH5W.js +2 -0
  92. package/dist-cli/chunks/{what-happened-2DEQUI25.js → what-happened-4GGACNI4.js} +2 -2
  93. package/dist-lib/agent-daemon-client.cjs +1 -1
  94. package/dist-lib/agent-events.cjs +1 -1
  95. package/dist-lib/agent-identity.cjs +1 -1
  96. package/dist-lib/agent-sessions.cjs +1 -1
  97. package/dist-lib/attached-projects.cjs +1 -1
  98. package/dist-lib/auth/shared-session.cjs +1 -1
  99. package/dist-lib/backend-origin.cjs +1 -1
  100. package/dist-lib/beta.cjs +1 -1
  101. package/dist-lib/beta.mjs +1 -1
  102. package/dist-lib/bridge-constants.cjs +1 -1
  103. package/dist-lib/cli-constants.cjs +1 -1
  104. package/dist-lib/config.cjs +1 -1
  105. package/dist-lib/detox/index.cjs +108 -12
  106. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  107. package/dist-lib/home-paths.cjs +1 -1
  108. package/dist-lib/host/bridge-host.cjs +1 -1
  109. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  110. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  111. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  112. package/dist-lib/host/websocket-proxy.cjs +1 -1
  113. package/dist-lib/index.cjs +1 -1
  114. package/dist-lib/jump-to-source-babel.cjs +1 -1
  115. package/dist-lib/menu.cjs +1 -1
  116. package/dist-lib/menu.mjs +1 -1
  117. package/dist-lib/metro.cjs +1 -1
  118. package/dist-lib/profiles.cjs +1 -1
  119. package/dist-lib/render-mode.cjs +1 -1
  120. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  121. package/dist-lib/sdk.cjs +57 -9
  122. package/dist-lib/sdk.mjs +57 -9
  123. package/dist-lib/skills.cjs +41 -15
  124. package/dist-lib/vite.cjs +1 -1
  125. package/package.json +1 -1
  126. package/skills/soot/SKILL.md +1 -0
  127. package/skills/sootsim-debug/SKILL.md +6 -8
  128. package/skills/sootsim-perf/SKILL.md +4 -4
  129. package/dist-cli/chunks/beta-VXRR4GRU.js +0 -2
  130. package/dist-cli/chunks/chunk-FZPRFSTA.js +0 -2
  131. package/dist-cli/chunks/chunk-NQDDEWYD.js +0 -1
  132. package/dist-cli/chunks/chunk-T7CWPTU7.js +0 -2
  133. package/dist-cli/chunks/chunk-TQ7WAA2M.js +0 -119
  134. package/dist-cli/chunks/chunk-WEBUMXLD.js +0 -97
  135. package/dist-cli/chunks/chunk-WF6AY4K4.js +0 -1
  136. package/dist-cli/chunks/cli-version-5DZ5FKJC.js +0 -2
  137. package/dist-cli/chunks/daemon-LOYTWGGF.js +0 -2
  138. package/dist-cli/chunks/drivers-Z2TX4DMF.js +0 -2
  139. package/dist-cli/chunks/flow-7XFQKTBU.js +0 -2
  140. package/dist-cli/chunks/help-ODEIEVZ6.js +0 -2
  141. package/dist-cli/chunks/inspect-KFGNZ2E3.js +0 -2
  142. package/dist-cli/chunks/install-desktop-GTMDR7D5.js +0 -2
  143. package/dist-cli/chunks/mode-OXPEBMF2.js +0 -111
  144. package/dist-cli/chunks/optional-demo-registry-CHOUOWFF.js +0 -2
  145. package/dist-cli/chunks/runtime-NCWCN66Y.js +0 -2
  146. package/dist-cli/chunks/store-5AQQ6HKE.js +0 -2
  147. package/dist-cli/chunks/telemetry-L2M7NRKA.js +0 -2
  148. package/dist-cli/chunks/upload-UQRYTSL2.js +0 -2
  149. package/dist-cli/chunks/web-YCDMLF4V.js +0 -2
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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;
@@ -1647,10 +1647,10 @@ var init_registry = __esm({
1647
1647
  versions: [
1648
1648
  {
1649
1649
  range: ">=1.0.0",
1650
- coverage: 0.7,
1651
- note: "HTML5 video playback works; player duration/currentTime not synced back from element",
1652
- working: "VideoView (HTML5 video element), useVideoPlayer/createVideoPlayer hooks, play/pause/seekBy/replay/replace/release/addListener/removeAllListeners, VideoView ref API (enterFullscreen/exitFullscreen/startPictureInPicture/stopPictureInPicture), isPictureInPictureSupported (returns false), VideoAirPlayButton (null noop), clearVideoCacheAsync/setVideoCacheSizeAsync/getCurrentVideoCacheSize",
1653
- missing: "player.duration stays 0 (no timeupdate listener), player.currentTime not synced from element, statusChange/volumeChange/timeUpdate events not emitted, useEvent hook not exported, DRM support absent"
1650
+ coverage: 0.88,
1651
+ note: "native-seam only \u2014 upstream expo-video JS runs unchanged; a host/page-thread HTMLVideoElement owns decode and timing, exact ExpoVideo player event payloads return through the host-service bridge, and transferable ImageBitmap frames enter the compositor live-frame mirror",
1652
+ working: "upstream VideoView/useVideoPlayer/createVideoPlayer and source parsing; real media metadata and first-frame rendering; play/pause/seekBy/replay/replace/release; statusChange, playingChange, playbackRateChange, volumeChange, mutedChange, playToEnd, timeUpdate, sourceChange, and sourceLoad object payloads; currentTime/duration/bufferedPosition synchronization; loop/mute/volume/rate/pitch properties; request headers; cache API noops and isPictureInPictureSupported=false",
1653
+ missing: "DRM, native controls, selectable audio/video/subtitle tracks, AirPlay, fullscreen and picture-in-picture presentation, live-stream latency/timestamps, thumbnail generation, and persistent video cache"
1654
1654
  }
1655
1655
  ]
1656
1656
  },
@@ -7700,10 +7700,10 @@ var init_registry = __esm({
7700
7700
  stubType: "native",
7701
7701
  versions: [
7702
7702
  {
7703
- range: ">=1.0.0",
7704
- coverage: 0.75,
7705
- note: "load-safe passthrough",
7706
- missing: "no native paste handler; sootsim TextInput supports paste natively"
7703
+ range: ">=0.1.0",
7704
+ coverage: 0.9,
7705
+ note: "native-seam ExpoPasteInput view manager (pass-through container); real TextInputWrapperView JS runs from bundle",
7706
+ missing: "onPaste never fires \u2014 sootsim keyboard has no paste pipeline into guest inputs"
7707
7707
  }
7708
7708
  ]
7709
7709
  },
@@ -15182,6 +15182,11 @@ __export(ws_bridge_exports, {
15182
15182
  worldForBridgePort: () => worldForBridgePort
15183
15183
  });
15184
15184
  function resolveBridgeWorld() {
15185
+ if (resolvedWorld) return resolvedWorld;
15186
+ resolvedWorld = resolveBridgeWorldFresh();
15187
+ return resolvedWorld;
15188
+ }
15189
+ function resolveBridgeWorldFresh() {
15185
15190
  const dev = readDevBridgeLockfile();
15186
15191
  if (dev && isDevBridgeLockfileFresh(dev)) {
15187
15192
  return {
@@ -15567,7 +15572,7 @@ async function callInBridge(bridge, path11, ...args) {
15567
15572
  async function callInBridgeWrite(bridge, path11, ...args) {
15568
15573
  return bridge.send({ type: "call", path: path11, args, acquireLock: true });
15569
15574
  }
15570
- var import_ws3, BridgeSimLockedError;
15575
+ var import_ws3, resolvedWorld, BridgeSimLockedError;
15571
15576
  var init_ws_bridge = __esm({
15572
15577
  "cli/ws-bridge.ts"() {
15573
15578
  "use strict";
@@ -15576,6 +15581,7 @@ var init_ws_bridge = __esm({
15576
15581
  init_cli_constants();
15577
15582
  init_home_paths();
15578
15583
  init_current_sim();
15584
+ resolvedWorld = null;
15579
15585
  BridgeSimLockedError = class extends Error {
15580
15586
  lock;
15581
15587
  constructor(message, lock) {
@@ -17269,6 +17275,9 @@ var init_bridge_flow_runner = __esm({
17269
17275
  if (args.error != null) {
17270
17276
  entry.error = args.error instanceof Error ? args.error.message : String(args.error);
17271
17277
  }
17278
+ if (args.screenshotPath) {
17279
+ entry.screenshotPath = args.screenshotPath;
17280
+ }
17272
17281
  this.flowTraceSteps.push(entry);
17273
17282
  }
17274
17283
  async stopRecording() {
@@ -17533,6 +17542,18 @@ var init_bridge_flow_runner = __esm({
17533
17542
  await sleep2(150);
17534
17543
  element = await this.findElement(opts);
17535
17544
  }
17545
+ if (!element) return element;
17546
+ const stabilityDeadline = Date.now() + 1200;
17547
+ let prev = element;
17548
+ while (Date.now() < stabilityDeadline) {
17549
+ await sleep2(120);
17550
+ const next = await this.findElement(opts);
17551
+ if (!next) break;
17552
+ const moved = Math.abs(next.absolutePosition.x - prev.absolutePosition.x) > 0.5 || Math.abs(next.absolutePosition.y - prev.absolutePosition.y) > 0.5 || Math.abs(next.layout.width - prev.layout.width) > 0.5 || Math.abs(next.layout.height - prev.layout.height) > 0.5;
17553
+ element = next;
17554
+ if (!moved) return element;
17555
+ prev = next;
17556
+ }
17536
17557
  return element;
17537
17558
  }
17538
17559
  replayTargetForElement(opts, element, tapTarget) {
@@ -17821,10 +17842,11 @@ var init_bridge_flow_runner = __esm({
17821
17842
  const framed = await composeFramedScreenshot(rawBuffer, model);
17822
17843
  fs9.writeFileSync(outputPath, framed);
17823
17844
  console.log(`[flow] screenshot: ${outputPath} (frame: ${model})`);
17824
- return;
17845
+ return outputPath;
17825
17846
  }
17826
17847
  fs9.writeFileSync(outputPath, rawBuffer);
17827
17848
  console.log(`[flow] screenshot: ${outputPath}`);
17849
+ return outputPath;
17828
17850
  }
17829
17851
  async readCurrentDeviceModel() {
17830
17852
  const settings = await this.bridge.send({
@@ -18506,8 +18528,10 @@ var init_bridge_flow_runner = __esm({
18506
18528
  step.runScript);
18507
18529
  const STEP_WATCHDOG_MS = 1e4;
18508
18530
  const body = this.runStepInner(step);
18531
+ let screenshotPath;
18509
18532
  if (hasExplicitWait) {
18510
- await body;
18533
+ const result = await body;
18534
+ if (typeof result === "string") screenshotPath = result;
18511
18535
  } else {
18512
18536
  let timer = null;
18513
18537
  const watchdog = new Promise((_, reject) => {
@@ -18520,7 +18544,8 @@ var init_bridge_flow_runner = __esm({
18520
18544
  }, STEP_WATCHDOG_MS);
18521
18545
  });
18522
18546
  try {
18523
- await Promise.race([body, watchdog]);
18547
+ const result = await Promise.race([body, watchdog]);
18548
+ if (typeof result === "string") screenshotPath = result;
18524
18549
  } finally {
18525
18550
  if (timer) clearTimeout(timer);
18526
18551
  }
@@ -18534,7 +18559,8 @@ var init_bridge_flow_runner = __esm({
18534
18559
  stepName,
18535
18560
  targetLabel,
18536
18561
  startedAtMs,
18537
- status: "success"
18562
+ status: "success",
18563
+ screenshotPath
18538
18564
  });
18539
18565
  } catch (error) {
18540
18566
  if (this.isOptional(step)) {
@@ -18579,7 +18605,7 @@ var init_bridge_flow_runner = __esm({
18579
18605
  else if (step.pressKey) await this.pressKey(step.pressKey);
18580
18606
  else if (step.dispatchKey) await this.dispatchKey(step.dispatchKey);
18581
18607
  else if (step.waitFor) await this.waitFor(step.waitFor);
18582
- else if (step.takeScreenshot) await this.takeScreenshot(step.takeScreenshot);
18608
+ else if (step.takeScreenshot) return this.takeScreenshot(step.takeScreenshot);
18583
18609
  else if (step.swipe) {
18584
18610
  if (step.swipe.start && step.swipe.end) {
18585
18611
  await this.swipeCoords(step.swipe.start, step.swipe.end, step.swipe.duration);
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.216 | (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.214",
3
+ "version": "0.1.216",
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",
@@ -22,6 +22,7 @@ automation, inspecting the render tree, and managing sims.
22
22
  | `sootsim maestro` | author, generate, and run Maestro YAML flows against sootsim |
23
23
  | `sootsim detox` | run existing Detox suites against sootsim on headless Chromium |
24
24
  | `sootsim record` | capture the live sim as webm/mp4/gif, or sample N png frames (--frames) |
25
+ | `sootsim film` | record a flow on the flat canvas, replay it on the 3d device stage under a camera cinematic, save a clip |
25
26
  | `sootsim storage` | manage guest app storage and launch profiles |
26
27
  | `sootsim perf` | CPU, React render, and shell frame profiling |
27
28
  | `sootsim describe` | curated human-readable UI summary (default inspection tool) |
@@ -20,7 +20,7 @@ load `/sootsim-visual` instead.
20
20
  for any rendering, animation, gesture, or interaction bug, reach for the
21
21
  sootsim CLI debug tooling **first** — `describe` and `find` to read the
22
22
  tree, `debug snapshot` + `debug diff` to capture before/after, `debug
23
- recent` on a channel and `debug perf` for frame-by-frame stats, and the
23
+ recent` on a channel and `perf shell` for frame-by-frame stats, and the
24
24
  timeline for "what just happened". **do not** debug these by eye with
25
25
  screenshots, sprinkle `console.log` through the render path, or spin up a
26
26
  one-off browser-automation script. the canvas has no DOM to inspect, and a
@@ -172,15 +172,13 @@ you're done when:
172
172
  ## branch — performance
173
173
 
174
174
  ```sh
175
- sootsim debug perf start # arm capture (also clears prior frames)
175
+ sootsim perf shell start # arm capture (also clears prior frames)
176
176
  # reproduce the slow interaction
177
- sootsim debug perf stop # full report
178
- sootsim debug perf stop --json # machine-readable summary
179
- sootsim debug perf frames # per-frame ring breakdown
180
- sootsim debug perf worst # the slowest frames first
177
+ sootsim perf shell stop # full report, including worst frames
178
+ sootsim perf shell stop --json # machine-readable summary
181
179
  ```
182
180
 
183
- `debug perf` output:
181
+ `perf shell` output:
184
182
 
185
183
  ```
186
184
  frames: 847
@@ -340,7 +338,7 @@ type names sneak in).
340
338
  loaded. load `/sootsim-setup` and re-confirm.
341
339
  - **`find` returns multiple matches** — narrow with `--testid`,
342
340
  `--visible`, or both.
343
- - **`debug perf` reports zero frames** — you didn't run `perf start`
341
+ - **`perf shell` reports zero frames** — you didn't run `perf shell start`
344
342
  first, or the capture window closed before any frame committed.
345
343
  - **`get a11y --issues` returns 100+ items** — sort by P0 first; fixing
346
344
  one label often cascades to a parent's a11y subtree.
@@ -18,7 +18,7 @@ indict, remeasure — and every wasted week came from skipping a step.
18
18
 
19
19
  1. **measure the shell, in the right browser.** the shell worker owns every
20
20
  painted pixel; the tenant hasn't painted since the two-worker split. the
21
- CLI's `debug perf` reads the shell profile (the tenant sampler that
21
+ CLI's `perf shell` reads the shell profile (the tenant sampler that
22
22
  reported `avg 0.48ms (2069 fps)` for a visibly janky scroll was removed).
23
23
  browser matters just as much: playwright's bundled headless chromium has
24
24
  NO GPU — CanvasKit falls back to SwiftShader and every number lies high.
@@ -42,10 +42,10 @@ indict, remeasure — and every wasted week came from skipping a step.
42
42
  ## measuring
43
43
 
44
44
  ```sh
45
- sootsim debug perf start # arm shell frame capture (clears prior)
45
+ sootsim perf shell start # arm shell frame capture (clears prior)
46
46
  # reproduce — e.g. 8 fling swipes:
47
47
  # for i in {1..8}; do sootsim do swipe 196 650 196 250 8 8 --no-wait; sleep 0.9; done
48
- sootsim debug perf stop # report (add --json for scripting)
48
+ sootsim perf shell stop # report (add --json for scripting)
49
49
  ```
50
50
 
51
51
  the report and how to read it:
@@ -83,7 +83,7 @@ sootsim debug enable layout,render && sootsim debug recent layout 40
83
83
  work-per-painted-frame cannot see a frame that was never delivered — host
84
84
  rAF starved, shell worker descheduled, vsync message stuck behind a busy
85
85
  queue. the report shows low avg and zero jank while the user sees stutter.
86
- the `cadence` section of `debug perf stop` measures the delivery side and
86
+ the `cadence` section of `perf shell stop` measures the delivery side and
87
87
  attributes a missing frame to its hop:
88
88
 
89
89
  - `display clock / host rAF interval` — stretch here (gaps >1.5x median)
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c,d}from"./chunk-KHIKG5LO.js";import"./chunk-TI2ZOHON.js";export{d as BETA_ASK_HEADLINE,b as BETA_LABEL,c as BETA_TAGLINE,a as IS_BETA};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- var m={"--help":{type:"boolean",short:"-h"},"--version":{type:"boolean",short:"-V"},"--verbose":{type:"boolean",short:"-v"},"--port":{type:"number",short:"-p"},"--device":{type:"string",short:"-d"},"--theme":{type:"string",short:"-t"},"--headless":{type:"boolean"},"--driver":{type:"string"},"--sim":{type:"string"},"--session":{type:"string"},"--tab":{type:"string"}},p=new Set(["list","describe","find","get","do","wait","network","logs","shell"]),b=new Set(["do","get","wait","shell","debug"]),d=new Set(["detox","maestro","record","storage","perf","screenshot","mode","inspect","debug","timeline","what-happened","shell","assert","device","open","list","use","claim","close","compat","desktop","login","logout","auth","setup","serve","daemon","runtime","upgrade","version","skill","config","app-fonts","agent-wrapper","agent",...p]);function h(c){let r=c.slice(2),e={command:null,commandArgs:[],globalFlags:{},help:!1,version:!1,verbose:!1},s=0;for(;s<r.length;){let o=r[s];if(o==="--"){e.commandArgs.push(...r.slice(s+1));break}let i=Object.entries(m).find(([a,t])=>a===o||t.short===o);if(i){let[a,t]=i,l=a.replace(/^--/,"");if(t.type==="boolean")e.globalFlags[l]=!0,s++;else{let n=r[s+1];if(n===void 0||n.startsWith("-")){console.error(` warning: ${o} requires a value`),s++;continue}if(t.type==="number"){let g=Number(n);if(Number.isNaN(g)){console.error(` warning: ${o} requires a number, got "${n}"`),s+=2;continue}e.globalFlags[l]=g}else e.globalFlags[l]=n;s+=2}continue}if(!e.command&&!o.startsWith("-")){let a=o.indexOf("-");if(a>0){let t=o.slice(0,a),l=o.slice(a+1);if(b.has(t)&&l.length>0){e.command=t;let n=r.slice(s+1);e.commandArgs=[l,...n[0]==="--"?n.slice(1):n];break}}if(d.has(o)){e.command=o;let t=r.slice(s+1);e.commandArgs=t[0]==="--"?t.slice(1):t;break}e.commandArgs=r.slice(s);break}e.commandArgs.push(o),s++}return e.help=!!e.globalFlags.help,e.version=!!e.globalFlags.version,e.verbose=!!e.globalFlags.verbose,e}export{p as a,h as b};
@@ -1 +0,0 @@
1
- /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.214 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- function o(e,r,n,i){return{width:3,ringToggle:{top:e[0],height:e[1]},volumeUp:{top:r[0],height:r[1]},volumeDown:{top:n[0],height:n[1]},lock:{top:i[0],height:i[1]}}}var b={width:2.5,lock:{top:188.7,height:68.1},ringToggle:{top:113.2,height:36},volumeUp:{top:188.2,height:68.1},volumeDown:{top:269,height:68.1}},d={width:3,lock:{top:238,height:78},ringToggle:{top:-1e3,height:0},volumeUp:{top:336,height:62},volumeDown:{top:408,height:62}},g={width:3,lock:{top:248,height:72},ringToggle:{top:-1e3,height:0},volumeUp:{top:144,height:62},volumeDown:{top:216,height:62}},a=48;function t(e){return{...e,platform:"ios",navigationBarHeight:0,navigationBarMode:e.homeIndicatorHeight>0?"gesture":"none",displayCutout:{top:e.dynamicIsland?e.statusBarHeight:0,bottom:0,left:0,right:0},cameraCutout:null,osVersion:e.iosVersion,androidApiLevel:null,systemName:"iOS",manufacturer:"Apple",brand:"Apple",modelName:e.name}}var p={"canvas-workspace":t({name:"Canvas Workspace",width:1440,height:900,scale:1,statusBarHeight:0,homeIndicatorHeight:0,cornerRadius:0,bezelWidth:16,dynamicIsland:null,safeAreaInsets:{top:0,bottom:0,left:0,right:0},iosVersion:"26.4",physicalPPI:110,hardwareButtons:o([185.8,41.7],[258.2,67.6],[344,67.6],[281.5,106.9]),experimental:!0}),"iphone-se":t({name:"iPhone SE",width:375,height:667,scale:2,statusBarHeight:20,homeIndicatorHeight:0,cornerRadius:0,bezelWidth:28.7,dynamicIsland:null,safeAreaInsets:{top:20,bottom:0,left:0,right:0},iosVersion:"15.8",physicalPPI:326,hardwareButtons:b}),"iphone-14":t({name:"iPhone 14",width:390,height:844,scale:3,statusBarHeight:47,homeIndicatorHeight:34,cornerRadius:49,bezelWidth:21.8,dynamicIsland:null,safeAreaInsets:{top:47,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:o([176.1,35.8],[239.5,71.5],[325.2,71.5],[262.7,110.8])}),"iphone-15":t({name:"iPhone 15",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:58,bezelWidth:20.5,dynamicIsland:{width:126,height:37.3,top:14.1},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:o([181.2,35.8],[246.4,67.6],[332.1,67.6],[269.6,106.9])}),"iphone-15-plus":t({name:"iPhone 15 Plus",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:58,bezelWidth:20.5,dynamicIsland:{width:126,height:37.3,top:11.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:o([175.8,35.8],[241.1,67.6],[326.8,67.6],[264.3,106.9])}),"iphone-15-pro":t({name:"iPhone 15 Pro",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:58,bezelWidth:17.8,dynamicIsland:{width:126,height:38,top:13.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"18.2",physicalPPI:460,hardwareButtons:o([174.1,36.5],[240.4,67.6],[326.1,67.6],[286.9,106.9])}),"iphone-15-pro-max":t({name:"iPhone 15 Pro Max",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:58,bezelWidth:17.8,dynamicIsland:{width:126,height:38,top:13.3},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"18.2",physicalPPI:460,hardwareButtons:o([174.1,36.5],[240.4,67.6],[326.1,67.6],[286.9,106.9])}),"iphone-16":t({name:"iPhone 16",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:58,bezelWidth:20.5,dynamicIsland:{width:126,height:37.3,top:11},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([185.8,41.7],[258.2,67.6],[344,67.6],[281.5,106.9])}),"iphone-16-plus":t({name:"iPhone 16 Plus",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:58,bezelWidth:20.6,dynamicIsland:{width:126,height:37.3,top:11.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([185.8,41.7],[258.2,67.6],[344,67.6],[281.5,106.9])}),"iphone-16-pro":t({name:"iPhone 16 Pro",width:402,height:874,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:64,bezelWidth:16.3,dynamicIsland:{width:126,height:38,top:13.5},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([186.4,41.7],[258.9,67.6],[344.6,67.6],[282.1,106.9])}),"iphone-16-pro-max":t({name:"iPhone 16 Pro Max",width:440,height:956,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:64,bezelWidth:14.3,dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([185,41.7],[257.4,67.6],[343.2,67.6],[280.7,106.9])}),"iphone-17":t({name:"iPhone 17",width:402,height:874,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:64,bezelWidth:16.2,dynamicIsland:{width:126,height:37.3,top:14},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([186.4,41.7],[258.9,67.6],[344.6,67.6],[282,106.9])}),"iphone-17-air":t({name:"iPhone Air",width:420,height:912,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:64,bezelWidth:15.6,dynamicIsland:{width:126,height:38,top:20},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([185.6,40.5],[257.4,67.6],[343.2,67.6],[280.7,106.9])}),"iphone-17-pro":t({name:"iPhone 17 Pro",width:402,height:874,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:64,bezelWidth:17.4,dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([187.7,41.7],[263.2,61.6],[348.9,61.6],[283.4,106.9])}),"iphone-17-pro-max":t({name:"iPhone 17 Pro Max",width:440,height:956,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:64,bezelWidth:17,dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:o([187.7,41.7],[260.1,67.6],[345.9,67.6],[283.4,106.9])}),"pixel-8":{platform:"android",name:"Pixel 8",width:412,height:915,scale:2.625,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:a,navigationBarMode:"gesture",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:39,bezelWidth:13,dynamicIsland:null,cameraCutout:{diameter:24},safeAreaInsets:{top:40,bottom:a,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 8",physicalPPI:428,hardwareButtons:d},"pixel-8-three-button":{platform:"android",name:"Pixel 8 (3-button)",width:412,height:915,scale:2.625,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:48,navigationBarMode:"three-button",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:39,bezelWidth:13,dynamicIsland:null,cameraCutout:{diameter:24},safeAreaInsets:{top:40,bottom:48,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 8",physicalPPI:428,hardwareButtons:d},"pixel-9-pro-xl":{platform:"android",name:"Pixel 9 Pro XL",width:448,height:997,scale:3,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:a,navigationBarMode:"gesture",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:41,bezelWidth:12,dynamicIsland:null,cameraCutout:{diameter:24},safeAreaInsets:{top:40,bottom:a,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 9 Pro XL",physicalPPI:486,hardwareButtons:d},"galaxy-s24":{platform:"android",name:"Galaxy S24",width:360,height:780,scale:3,statusBarHeight:36,homeIndicatorHeight:0,navigationBarHeight:a,navigationBarMode:"gesture",displayCutout:{top:36,bottom:0,left:0,right:0},cornerRadius:36,bezelWidth:8,dynamicIsland:null,cameraCutout:{diameter:18},safeAreaInsets:{top:36,bottom:a,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Samsung",brand:"samsung",modelName:"SM-S921B",physicalPPI:416,hardwareButtons:g},"galaxy-s24-ultra":{platform:"android",name:"Galaxy S24 Ultra",width:384,height:824,scale:3.75,statusBarHeight:36,homeIndicatorHeight:0,navigationBarHeight:a,navigationBarMode:"gesture",displayCutout:{top:36,bottom:0,left:0,right:0},cornerRadius:24,bezelWidth:9,dynamicIsland:null,cameraCutout:{diameter:18},safeAreaInsets:{top:36,bottom:a,left:0,right:0},osVersion:"15",iosVersion:"",androidApiLevel:35,systemName:"Android",manufacturer:"Samsung",brand:"samsung",modelName:"SM-S928B",physicalPPI:505,hardwareButtons:g}},m="iphone-17-pro";function P(e){return p[e]}function h(){return Object.keys(p)}function v(){return h().filter(e=>!p[e].experimental)}var l={"iphone-6-9":{name:"iphone-6-9",label:'iPhone 6.7"',width:1284,height:2778,store:"apple"},"iphone-6-1":{name:"iphone-6-1",label:'iPhone 6.5"',width:1242,height:2688,store:"apple"},"android-phone":{name:"android-phone",label:"Google Play phone",width:1080,height:1920,store:"google"},"android-tablet-7":{name:"android-tablet-7",label:'Google Play 7" tablet',width:1200,height:1920,store:"google"},"android-tablet-10":{name:"android-tablet-10",label:'Google Play 10" tablet',width:1600,height:2560,store:"google"}},c={dark:{type:"gradient",direction:180,glow:"#4caeff",stops:[{offset:0,color:"#111827"},{offset:40,color:"#101725"},{offset:100,color:"#06080d"}]},cyan:{type:"gradient",direction:180,glow:"#25c3ec",stops:[{offset:0,color:"#1b465c"},{offset:32,color:"#122336"},{offset:100,color:"#05070b"}]},gold:{type:"gradient",direction:180,glow:"#ffc25a",stops:[{offset:0,color:"#3b2f1a"},{offset:34,color:"#18140d"},{offset:100,color:"#050505"}]},red:{type:"gradient",direction:180,glow:"#ff6178",stops:[{offset:0,color:"#3e1018"},{offset:35,color:"#17080c"},{offset:100,color:"#050405"}]}},B={color:"#25c3ec",blur:120,spread:52,opacity:.34},I="iphone-17-pro";var y=[{name:"white",value:"#ffffff"},{name:"gray-light",value:"#d1d5db"},{name:"gray",value:"#6b7280"},{name:"gray-dark",value:"#3b4350"},{name:"slate",value:"#2a3644"},{name:"black",value:"#000000"},{name:"cyan",value:"#25c3ec"},{name:"blue",value:"#3f7cff"},{name:"teal",value:"#1fc7b4"},{name:"green",value:"#42c95d"},{name:"lime",value:"#92d21b"},{name:"gold",value:"#f5c518"},{name:"orange",value:"#ff912e"},{name:"coral",value:"#ff6f5b"},{name:"red",value:"#ff4f6f"},{name:"berry",value:"#d054ff"},{name:"magenta",value:"#ff4eb8"}],f=Object.fromEntries(y.map(e=>[e.name,e.value]));function T(e){return f[e]??f.gray}function R(e){return Object.prototype.hasOwnProperty.call(l,e)?l[e]:null}function S(e){return{type:e.type,color:e.color,direction:e.direction,glow:e.glow,stops:e.stops?.map(r=>({...r}))}}function A(e){return Object.prototype.hasOwnProperty.call(c,e)?S(c[e]):null}var u={deviceModel:{type:"enum",default:m,description:"device model to simulate",cliFlag:"device",cliFlagShort:"d",options:h(),group:"device"},orientation:{type:"enum",default:"portrait",description:"screen orientation",cliFlag:"orientation",options:["portrait","landscape"],group:"device"},colorScheme:{type:"enum",default:"auto",description:"color scheme (auto follows system preference)",cliFlag:"theme",cliFlagShort:"t",options:["light","dark","auto"],group:"appearance"},reduceMotion:{type:"boolean",default:!1,description:"reduce motion",group:"appearance"},boldText:{type:"boolean",default:!1,description:"bold text",group:"appearance"},fontSize:{type:"number",default:1,description:"font size multiplier (1.0 = default)",group:"appearance",validate:e=>e>=.5&&e<=2},networkCondition:{type:"enum",default:"wifi",description:"simulated network condition",cliFlag:"network",options:["wifi","lte","fast-3g","slow-3g","offline"],group:"network"},language:{type:"string",default:"en",description:"language code (ISO 639-1)",cliFlag:"language",group:"locale"},region:{type:"string",default:"US",description:"region code (ISO 3166-1)",cliFlag:"region",group:"locale"},showTouches:{type:"boolean",default:!1,description:"show touch indicators",group:"simulator"},showFrame:{type:"boolean",default:!0,description:"show device frame",cliFlag:"frame",group:"simulator"},showTopBar:{type:"boolean",default:!0,description:"show simulator top bar",group:"simulator"},screenshotMode:{type:"boolean",default:!1,description:"show screenshot composition mode in the browser shell",group:"simulator"},threeMode:{type:"boolean",default:!1,description:"show the experimental 3d device stage in the browser shell",group:"simulator"},threeRecordingEditor:{type:"boolean",default:!1,description:"dock the 3d recording editor in the 3d stage (toggled from its rail)",group:"simulator"},screenshotCanvas:{type:"enum",default:"iphone-6-9",description:"target app-store canvas preset for screenshot mode",options:Object.keys(l),group:"simulator"},screenshotBackground:{type:"enum",default:"dark",description:"background preset rendered inside the screenshot canvas",options:Object.keys(c),group:"simulator"},screenshotText:{type:"enum",default:"bold-top",description:"text layout preset for the screenshot canvas",options:["bold-top","editorial-left","minimal-bottom","none"],group:"simulator"},screenshotPose:{type:"enum",default:"straight",description:"device pose preset inside the screenshot canvas",options:["straight","tilted-left","tilted-right","cut-bottom","cut-top"],group:"simulator"},screenshotDynamicSize:{type:"boolean",default:!1,description:"let the screenshot canvas rect fit available space (off = pin to exact preset pixels)",group:"simulator"},showStatusBar:{type:"boolean",default:!0,description:"show status bar",group:"simulator"},showHomeIndicator:{type:"boolean",default:!0,description:"show home indicator",group:"simulator"},alwaysShowLiveWebViews:{type:"boolean",default:!1,description:"always render WebViews as live browser views",group:"simulator"},a11yMode:{type:"enum",default:"delayed",description:"accessibility tree sync mode (off, delayed=100ms, active=30ms)",options:["off","delayed","active"],group:"simulator"},a11yDepth:{type:"enum",default:"deep",description:"accessibility tree structure depth (shallow or deep)",options:["shallow","deep"],group:"simulator"},inspectMode:{type:"boolean",default:!1,description:"inspect mode",group:"simulator"},errorReporting:{type:"boolean",default:!1,description:"send anonymous crash reports",group:"privacy"},agentProvider:{type:"enum",default:"codex",description:"ai agent used by the sootsim agent prompt bar",options:["codex","claude"],group:"agent"},onboardingComplete:{type:"boolean",default:!1,description:"first-run onboarding completed",group:"beta"},betaConsentVersion:{type:"number",default:0,description:"last accepted beta telemetry policy version",group:"beta"},detailedTelemetry:{type:"boolean",default:!0,description:"send detailed usage telemetry (sessions, perf samples)",group:"beta"}};function w(){if(typeof window>"u")return{};let e={};try{let r=new URLSearchParams(window.location.search),n=r.get("device");n&&u.deviceModel.options?.includes(n)&&(e.deviceModel=n);let i=r.get("colorScheme")??r.get("theme");i&&u.colorScheme.options?.includes(i)&&(e.colorScheme=i);let s=r.get("alwaysShowLiveWebViews");s==="1"||s==="true"?e.alwaysShowLiveWebViews=!0:(s==="0"||s==="false")&&(e.alwaysShowLiveWebViews=!1)}catch{}return e}function H(){let e={};for(let[r,n]of Object.entries(u))e[r]=n.default;return Object.assign(e,w()),e}export{B as a,I as b,T as c,R as d,S as e,A as f,p as g,P as h,v as i,u as j,w as k,H as l};