sootsim 0.1.168 → 0.1.170

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 (189) hide show
  1. package/README.md +66 -63
  2. package/detox/index.ts +3 -3
  3. package/dist-cli/bin.js +3 -3
  4. package/dist-cli/chunks/agent-3C2BKQKX.js +46 -0
  5. package/dist-cli/chunks/{agent-wrapper-M32Q4WRZ.js → agent-wrapper-OIKCYOXZ.js} +2 -2
  6. package/dist-cli/chunks/{app-fonts-QJCMHTWY.js → app-fonts-25O32NAP.js} +2 -2
  7. package/dist-cli/chunks/{assert-FUPVKOCV.js → assert-ONEP4NQU.js} +2 -2
  8. package/dist-cli/chunks/beta-4E5USTEI.js +2 -0
  9. package/dist-cli/chunks/{camera-6Z3YMMEG.js → camera-RORW4MAA.js} +2 -2
  10. package/dist-cli/chunks/{chunk-MHEP6UMF.js → chunk-25RFZ6WP.js} +6 -6
  11. package/dist-cli/chunks/chunk-35GMFXVJ.js +2 -0
  12. package/dist-cli/chunks/{chunk-BKYCQJKE.js → chunk-3TM7DHWE.js} +2 -2
  13. package/dist-cli/chunks/{chunk-MGB5W5VY.js → chunk-4XVY5TUF.js} +2 -2
  14. package/dist-cli/chunks/{chunk-2DDHS4Z3.js → chunk-5ZHUPPS5.js} +1 -1
  15. package/dist-cli/chunks/{chunk-MO3L5VGD.js → chunk-6FAEORJ2.js} +2 -2
  16. package/dist-cli/chunks/{chunk-HIAR3KTT.js → chunk-6TSXXN2W.js} +4 -4
  17. package/dist-cli/chunks/chunk-AJF3QF4K.js +1 -0
  18. package/dist-cli/chunks/{chunk-QMQBMB4S.js → chunk-AUCNBB6Q.js} +2 -2
  19. package/dist-cli/chunks/{chunk-27Q45J2N.js → chunk-BP3EGFER.js} +2 -2
  20. package/dist-cli/chunks/{chunk-XWG6NJJE.js → chunk-DAXME77O.js} +3 -3
  21. package/dist-cli/chunks/chunk-DGJTEFE7.js +13 -0
  22. package/dist-cli/chunks/chunk-DIRDEKRW.js +23 -0
  23. package/dist-cli/chunks/{chunk-QWNLVJ4P.js → chunk-DKTC53HV.js} +1 -1
  24. package/dist-cli/chunks/{chunk-QBYYAPTB.js → chunk-DWXC25XG.js} +1 -1
  25. package/dist-cli/chunks/{chunk-OC4Y3UIV.js → chunk-E3FKMY5E.js} +1 -1
  26. package/dist-cli/chunks/chunk-ER4GBJRY.js +2 -0
  27. package/dist-cli/chunks/chunk-EX6V4ZV6.js +6 -0
  28. package/dist-cli/chunks/{chunk-MRPFNK2L.js → chunk-GQH3PD3W.js} +5 -5
  29. package/dist-cli/chunks/{chunk-IHVCKNFX.js → chunk-GST4YSBO.js} +4 -4
  30. package/dist-cli/chunks/{chunk-YNTWHWFY.js → chunk-I4RV5I6V.js} +1 -1
  31. package/dist-cli/chunks/{chunk-AFPKG2L6.js → chunk-I5WXVKR6.js} +1 -1
  32. package/dist-cli/chunks/{chunk-WUKEI6SL.js → chunk-IO7KAVFK.js} +2 -2
  33. package/dist-cli/chunks/{chunk-7YQ7CJFO.js → chunk-LMX7UB5T.js} +2 -2
  34. package/dist-cli/chunks/{chunk-ZIEXUO4S.js → chunk-N4YCSOCR.js} +2 -2
  35. package/dist-cli/chunks/{chunk-YR7WIUVL.js → chunk-NI3L4A65.js} +2 -2
  36. package/dist-cli/chunks/{chunk-TXZKEW6C.js → chunk-ODGEH6OW.js} +2 -2
  37. package/dist-cli/chunks/{chunk-LCHPOJOO.js → chunk-Q4NDYO2U.js} +1 -1
  38. package/dist-cli/chunks/{chunk-SHCQRQJA.js → chunk-QPRF3UYX.js} +2 -2
  39. package/dist-cli/chunks/chunk-QXJMXSQP.js +2 -0
  40. package/dist-cli/chunks/chunk-RLKSLUNR.js +2 -0
  41. package/dist-cli/chunks/{chunk-XUABY4IN.js → chunk-S244IT4W.js} +1 -1
  42. package/dist-cli/chunks/chunk-SDHOM6ZG.js +62 -0
  43. package/dist-cli/chunks/{chunk-ENK2SG5R.js → chunk-TXKOJ3P5.js} +1 -1
  44. package/dist-cli/chunks/{chunk-QGL6XWHB.js → chunk-UDMJSFSH.js} +8 -8
  45. package/dist-cli/chunks/{chunk-FZ656TJA.js → chunk-ULV4PWN4.js} +1 -1
  46. package/dist-cli/chunks/{chunk-VHVFXSXT.js → chunk-V4HTQPMA.js} +2 -2
  47. package/dist-cli/chunks/chunk-VATHADSI.js +2 -0
  48. package/dist-cli/chunks/{chunk-BSKD5K5N.js → chunk-VUOCUCJ2.js} +2 -2
  49. package/dist-cli/chunks/{chunk-BUCBIG2A.js → chunk-WN7R4GL4.js} +1 -1
  50. package/dist-cli/chunks/chunk-XOTJD6PU.js +118 -0
  51. package/dist-cli/chunks/chunk-XUNPVF5K.js +1 -0
  52. package/dist-cli/chunks/{chunk-SMBSZIDN.js → chunk-YMFSRCHL.js} +4 -4
  53. package/dist-cli/chunks/{chunk-JJIJVKAV.js → chunk-YV74D4MG.js} +2 -2
  54. package/dist-cli/chunks/{chunk-5GGI6NGS.js → chunk-YVTWSC5Y.js} +3 -3
  55. package/dist-cli/chunks/cli-version-EKKWCHRX.js +2 -0
  56. package/dist-cli/chunks/{compat-CH6BYJ4T.js → compat-ZVZM5TML.js} +3 -3
  57. package/dist-cli/chunks/control-TWINYHMY.js +2 -0
  58. package/dist-cli/chunks/{cpu-profile-VMHZN3WB.js → cpu-profile-RWGQTWLP.js} +2 -2
  59. package/dist-cli/chunks/daemon-AOSMNBD4.js +2 -0
  60. package/dist-cli/chunks/{debug-WQP3TJ62.js → debug-R7PL3MHF.js} +5 -5
  61. package/dist-cli/chunks/{detox-IAWL5YVJ.js → detox-UIJMKIGQ.js} +2 -2
  62. package/dist-cli/chunks/{device-GYJ6BHY7.js → device-7SRVX2PU.js} +2 -2
  63. package/dist-cli/chunks/{diagnose-GFDUQYHG.js → diagnose-OXAKLLZT.js} +2 -2
  64. package/dist-cli/chunks/drivers-BPPG22VP.js +2 -0
  65. package/dist-cli/chunks/{electron-CF7HUVQL.js → electron-CTCH4VOL.js} +3 -3
  66. package/dist-cli/chunks/flow-KA2WCWDL.js +2 -0
  67. package/dist-cli/chunks/help-XBQIK2XY.js +2 -0
  68. package/dist-cli/chunks/{hints-HF2LDTK7.js → hints-P3ZIAP3Z.js} +2 -2
  69. package/dist-cli/chunks/home-paths-ZSCTLOYE.js +2 -0
  70. package/dist-cli/chunks/{inspect-P2MPMFR3.js → inspect-2ABU5WET.js} +24 -24
  71. package/dist-cli/chunks/{install-desktop-QYLXYZQJ.js → install-desktop-4NOQ3YY4.js} +3 -3
  72. package/dist-cli/chunks/{keys-LJ37JUG2.js → keys-RPVEUNUC.js} +2 -2
  73. package/dist-cli/chunks/{login-RUZ7MAPC.js → login-6D6DXBO3.js} +4 -4
  74. package/dist-cli/chunks/{logout-4RE2BP3H.js → logout-T5OSWDTJ.js} +2 -2
  75. package/dist-cli/chunks/{maestro-V62C4AQM.js → maestro-MKCHEOKA.js} +2 -2
  76. package/dist-cli/chunks/optional-demo-registry-EYD2K3QH.js +2 -0
  77. package/dist-cli/chunks/{preview-3HWBUCVM.js → preview-S52ZNGN2.js} +2 -2
  78. package/dist-cli/chunks/{profile-D2CAEFO5.js → profile-IG5F3LTL.js} +2 -2
  79. package/dist-cli/chunks/{react-PXYQBCAK.js → react-275HCOFC.js} +2 -2
  80. package/dist-cli/chunks/{record-R7IDN3T6.js → record-YT63SUHO.js} +4 -4
  81. package/dist-cli/chunks/runtime-WYZMDZAK.js +2 -0
  82. package/dist-cli/chunks/{screenshot-YGGPEX7B.js → screenshot-5AZ4MY3A.js} +4 -4
  83. package/dist-cli/chunks/{screenshot-mode-QDUWRQUF.js → screenshot-mode-4S4EX2XJ.js} +2 -2
  84. package/dist-cli/chunks/{screenshots-6PNFJNLF.js → screenshots-UUJNZSG7.js} +2 -2
  85. package/dist-cli/chunks/screenshots-capture-I66JD3AD.js +41 -0
  86. package/dist-cli/chunks/{server-7Q3NW5MV.js → serve-O46Q4WAD.js} +18 -17
  87. package/dist-cli/chunks/setup-C44N54O7.js +77 -0
  88. package/dist-cli/chunks/skills-PPVS4XOQ.js +40 -0
  89. package/dist-cli/chunks/{slides-HJXHSWEF.js → slides-ZWSZJZUY.js} +2 -2
  90. package/dist-cli/chunks/store-3SLGP5O3.js +2 -0
  91. package/dist-cli/chunks/telemetry-2XLLWARK.js +2 -0
  92. package/dist-cli/chunks/{test-4TUHEODP.js → test-362G4M5A.js} +3 -3
  93. package/dist-cli/chunks/{three-mode-IL5442GI.js → three-mode-JNVTM2UT.js} +2 -2
  94. package/dist-cli/chunks/{timeline-JILPOKRF.js → timeline-VKC6ULRK.js} +2 -2
  95. package/dist-cli/chunks/{upgrade-SL5WMHSF.js → upgrade-SJPX4SPA.js} +2 -2
  96. package/dist-cli/chunks/upload-MXOBV6RT.js +2 -0
  97. package/dist-cli/chunks/version-4Z7AFNH3.js +4 -0
  98. package/dist-cli/chunks/web-WB2I2AWL.js +2 -0
  99. package/dist-cli/chunks/{what-happened-KKAJOJWO.js → what-happened-KQCWMQJT.js} +3 -3
  100. package/dist-cli/chunks/{whoami-QDJPYI2O.js → whoami-K76PXAD4.js} +2 -2
  101. package/dist-lib/agent-daemon-client.cjs +4 -5
  102. package/dist-lib/agent-events.cjs +1 -1
  103. package/dist-lib/agent-sessions.cjs +1 -1
  104. package/dist-lib/attached-projects.cjs +1 -1
  105. package/dist-lib/auth/shared-session.cjs +1 -1
  106. package/dist-lib/backend-origin.cjs +1 -1
  107. package/dist-lib/beta.cjs +3 -6
  108. package/dist-lib/beta.mjs +3 -5
  109. package/dist-lib/bridge-constants.cjs +1 -1
  110. package/dist-lib/cli-constants.cjs +1 -1
  111. package/dist-lib/config.cjs +1 -1
  112. package/dist-lib/detox/index.cjs +4 -4
  113. package/dist-lib/dev-bundle-resolution.cjs +2 -9
  114. package/dist-lib/home-paths.cjs +59 -1
  115. package/dist-lib/host/bridge-host.cjs +67 -5
  116. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  117. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  118. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  119. package/dist-lib/host/websocket-proxy.cjs +1 -1
  120. package/dist-lib/index.cjs +2 -2
  121. package/dist-lib/menu.cjs +1 -1
  122. package/dist-lib/menu.mjs +1 -1
  123. package/dist-lib/metro.cjs +2 -2
  124. package/dist-lib/profiles.cjs +1 -1
  125. package/dist-lib/render-mode.cjs +1 -1
  126. package/dist-lib/scripts/dev-server-scanner.cjs +5 -4
  127. package/dist-lib/sdk.cjs +1 -1
  128. package/dist-lib/sdk.mjs +1 -1
  129. package/dist-lib/skills.cjs +136 -20
  130. package/dist-lib/vite.cjs +2 -2
  131. package/package.json +2 -1
  132. package/scripts/dev-server-scanner.ts +3 -4
  133. package/scripts/postinstall.cjs +2 -2
  134. package/scripts/preuninstall.cjs +5 -7
  135. package/skills/soot.md +178 -0
  136. package/skills/sootsim-debug.md +384 -0
  137. package/skills/sootsim-setup.md +96 -0
  138. package/skills/sootsim-test.md +292 -0
  139. package/skills/sootsim-visual.md +122 -0
  140. package/src/agent-daemon-client.ts +4 -14
  141. package/src/beta.ts +3 -5
  142. package/src/dev-bundle-resolution.ts +1 -14
  143. package/src/home-paths.ts +77 -2
  144. package/src/host/agent-host.ts +1 -1
  145. package/src/host/bridge-host.ts +65 -6
  146. package/src/metro-plugin.ts +1 -1
  147. package/src/runtime-assets.ts +1 -1
  148. package/src/skills/builtin/a11y-review.ts +4 -1
  149. package/src/skills/builtin/perf-profile.ts +4 -1
  150. package/src/skills/builtin/screenshot-all.ts +4 -1
  151. package/src/skills/builtin/visual-diff.ts +4 -1
  152. package/src/vite-plugin.ts +1 -0
  153. package/dist-cli/chunks/agent-V5N6TSVL.js +0 -46
  154. package/dist-cli/chunks/auto-bootstrap-BMAKK4FR.js +0 -2
  155. package/dist-cli/chunks/beta-ERD6Z2EE.js +0 -2
  156. package/dist-cli/chunks/chunk-2UDB2A2Z.js +0 -119
  157. package/dist-cli/chunks/chunk-4PXQB4KC.js +0 -2
  158. package/dist-cli/chunks/chunk-4TJ2FLZX.js +0 -2
  159. package/dist-cli/chunks/chunk-5PEYA6XI.js +0 -1
  160. package/dist-cli/chunks/chunk-6MBEHPFK.js +0 -1
  161. package/dist-cli/chunks/chunk-BLRVSHCX.js +0 -7
  162. package/dist-cli/chunks/chunk-EMWWY2MH.js +0 -2
  163. package/dist-cli/chunks/chunk-FAEIKMNH.js +0 -1
  164. package/dist-cli/chunks/chunk-L62FIJ3P.js +0 -2
  165. package/dist-cli/chunks/chunk-L7F7QBGM.js +0 -23
  166. package/dist-cli/chunks/chunk-MQWZBKOF.js +0 -5
  167. package/dist-cli/chunks/chunk-N6CHIBHJ.js +0 -79
  168. package/dist-cli/chunks/chunk-PPIRXSWS.js +0 -13
  169. package/dist-cli/chunks/cli-version-P4CDXF4L.js +0 -2
  170. package/dist-cli/chunks/config-ST33XAYN.js +0 -45
  171. package/dist-cli/chunks/control-FW6XTHQE.js +0 -2
  172. package/dist-cli/chunks/daemon-5DEUBHYC.js +0 -67
  173. package/dist-cli/chunks/drivers-VTVBB4KQ.js +0 -2
  174. package/dist-cli/chunks/flow-GZZ7OVM3.js +0 -2
  175. package/dist-cli/chunks/help-EUSCLRLF.js +0 -2
  176. package/dist-cli/chunks/home-paths-ZBDTVPMF.js +0 -2
  177. package/dist-cli/chunks/install-N4QT365P.js +0 -2
  178. package/dist-cli/chunks/launch-3TUC2YGM.js +0 -16
  179. package/dist-cli/chunks/optional-demo-registry-ZEPUCMEO.js +0 -2
  180. package/dist-cli/chunks/runtime-RQOM2I2S.js +0 -2
  181. package/dist-cli/chunks/runtime-delivery-K4LFILF7.js +0 -2
  182. package/dist-cli/chunks/setup-repo-UZMY3JFZ.js +0 -2
  183. package/dist-cli/chunks/skills-GDYPRMR5.js +0 -10
  184. package/dist-cli/chunks/start-HDWGM5WJ.js +0 -23
  185. package/dist-cli/chunks/store-5DYIIFYH.js +0 -2
  186. package/dist-cli/chunks/telemetry-TMT3DYZU.js +0 -2
  187. package/dist-cli/chunks/upload-35XW4DMZ.js +0 -2
  188. package/dist-cli/chunks/version-ZEBIO5HC.js +0 -4
  189. package/dist-cli/chunks/web-JICQ5RN4.js +0 -2
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.168 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.170 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.168 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.170 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.168 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.170 | (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;
@@ -33,6 +33,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
33
33
  var dev_server_scanner_exports = {};
34
34
  __export(dev_server_scanner_exports, {
35
35
  __applyManifestForTests: () => __applyManifestForTests,
36
+ __isSootSelfServerForTests: () => __isSootSelfServerForTests,
36
37
  __resetScannerCache: () => __resetScannerCache,
37
38
  __shouldReuseScannerCacheEntry: () => __shouldReuseScannerCacheEntry,
38
39
  discoverListeningPorts: () => discoverListeningPorts,
@@ -412,12 +413,11 @@ async function probePort(port, buildIconProxyUrl) {
412
413
  return null;
413
414
  }
414
415
  function isSootSelfServer(server) {
415
- const projectName = server.projectName?.trim().toLowerCase();
416
- if (projectName === "soot" || projectName === "sootsim") return true;
417
416
  const bundleId = server.bundleId?.trim().toLowerCase();
418
- if (bundleId?.startsWith("dev.soot")) return true;
417
+ if (bundleId?.startsWith("dev.sootsim.")) return true;
419
418
  return false;
420
419
  }
420
+ var __isSootSelfServerForTests = isSootSelfServer;
421
421
  var portCache = /* @__PURE__ */ new Map();
422
422
  var NEGATIVE_CACHE_TTL_MS = 3e4;
423
423
  var WEAK_RESULT_CACHE_TTL_MS = 1500;
@@ -507,6 +507,7 @@ async function scanDevServers(opts = {}) {
507
507
  // Annotate the CommonJS export names for ESM import in node:
508
508
  0 && (module.exports = {
509
509
  __applyManifestForTests,
510
+ __isSootSelfServerForTests,
510
511
  __resetScannerCache,
511
512
  __shouldReuseScannerCacheEntry,
512
513
  discoverListeningPorts,
package/dist-lib/sdk.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.168 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.170 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.168 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.170 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // cli/commands/inspect/core.ts
4
4
  function resolveMaxMsFlag(args, fallbackMs) {
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.168 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.170 | (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;
@@ -3249,8 +3249,8 @@ var init_registry = __esm({
3249
3249
  {
3250
3250
  range: ">=3.1.0",
3251
3251
  coverage: 0.85,
3252
- note: "ExpoSpeechRecognition module and Web Speech wrapper backed by browser SpeechRecognition when available",
3253
- working: "ExpoSpeechRecognitionModule start/stop/abort/state, native event addListener/remove, granted permission helpers, recognition availability, speech services/default-service helpers, supported locales, iOS audio-session getters/setters, ExpoWebSpeechRecognition class, grammar/list classes, constants",
3252
+ note: "native-seam only \u2014 upstream expo-speech-recognition JS (ExpoWebSpeechRecognition, useSpeechRecognitionEvent, constants, and direct module API) runs unchanged from the bundle; SootSim registers only the ExpoSpeechRecognition native module, backed by the host-service SpeechRecognition bridge when available",
3253
+ working: "ExpoSpeechRecognition native module start/stop/abort/state, native event addListener/remove, granted permission helpers, recognition availability, speech services/default-service helpers, supported-locales shape, iOS audio-session getters/setters; upstream ExpoWebSpeechRecognition class, grammar/list classes, hook, and constants stay authoritative",
3254
3254
  missing: "native SFSpeechRecognizer and Android SpeechRecognizer engines, real microphone permission prompts, audioSource transcription, recording persistence, locale installation data, offline model downloads, volume metering"
3255
3255
  }
3256
3256
  ]
@@ -5224,10 +5224,10 @@ var init_registry = __esm({
5224
5224
  versions: [
5225
5225
  {
5226
5226
  range: ">=0.7.0",
5227
- coverage: 0.9,
5228
- note: "Node crypto surface for React Native bundles; WebCrypto backs random/RSA/subtle, and audited sync primitives back Node-only synchronous hash/HMAC/AES/PBKDF2 contracts.",
5229
- working: "subtle/webcrypto forwarding, randomBytes/randomFill/randomInt/randomUUID, createHash/createHmac, pbkdf2 callback/promise form, pbkdf2Sync, AES-CBC/GCM/CTR encrypt/decrypt with auth tags, publicEncrypt/privateDecrypt for RSA-OAEP and RSA_PKCS1_PADDING, conversion helpers, constants used by Node crypto consumers",
5230
- missing: "non-WebCrypto legacy algorithms such as DES/RC4/ChaCha20 are not implemented."
5227
+ coverage: 0.82,
5228
+ note: "native-seam only \u2014 real react-native-quick-crypto JS runs from the bundle against a SootSim-provided global.__QuickCryptoProxy. The seam implements the synchronous native primitives that can be faithfully backed in the browser (random, hash/HMAC, PBKDF2, AES-CBC/CTR/GCM, AES secret-key handles) and leaves unsupported native-only RSA/sign/keygen paths as explicit unsupported operations.",
5229
+ working: "upstream package JS and export surface, global __QuickCryptoProxy install before module evaluation, random/randomFill/getRandomValues via upstream JS, createHash/createHmac host objects, pbkdf2 callback/promise form and pbkdf2Sync, AES-CBC/GCM/CTR host ciphers, AES WebCrypto secret-key import/export and encrypt/decrypt",
5230
+ missing: "synchronous RSA publicEncrypt/publicDecrypt/privateDecrypt, createSign/createVerify, generateKeyPair, RSA/ECDH WebCrypto key paths, AES-KW, and legacy ciphers such as DES/RC4/ChaCha20."
5231
5231
  }
5232
5232
  ]
5233
5233
  },
@@ -5237,10 +5237,10 @@ var init_registry = __esm({
5237
5237
  versions: [
5238
5238
  {
5239
5239
  range: ">=0.3.0",
5240
- coverage: 0.9,
5241
- note: "aliases the WebCrypto-backed react-native-quick-crypto implementation; upstream package is another native Node-crypto surface over Nitro Modules, so the same native crypto contract applies.",
5242
- working: "same coverage as react-native-quick-crypto: random, sync hash/HMAC, AES-CBC/GCM/CTR, PBKDF2/pbkdf2Sync, RSA-OAEP, RSA PKCS1 v1.5 via the RSA seam, subtle/webcrypto forwarding",
5243
- missing: "same limitations as react-native-quick-crypto: non-WebCrypto legacy algorithms"
5240
+ coverage: 0.55,
5241
+ note: "small compatibility surface backed by the react-native-quick-crypto native proxy for existing SootSim callers; this is not the quick-crypto package replacement and should be replaced by a native-seam-only Nitro Modules implementation when that package becomes a priority.",
5242
+ working: "createHash plus subtle/webcrypto references for load-safe consumers",
5243
+ missing: "full upstream react-native-nitro-crypto package JS/native contract is not modeled yet"
5244
5244
  }
5245
5245
  ]
5246
5246
  },
@@ -10350,10 +10350,8 @@ async function probePort(port, buildIconProxyUrl) {
10350
10350
  return null;
10351
10351
  }
10352
10352
  function isSootSelfServer(server) {
10353
- const projectName = server.projectName?.trim().toLowerCase();
10354
- if (projectName === "soot" || projectName === "sootsim") return true;
10355
10353
  const bundleId = server.bundleId?.trim().toLowerCase();
10356
- if (bundleId?.startsWith("dev.soot")) return true;
10354
+ if (bundleId?.startsWith("dev.sootsim.")) return true;
10357
10355
  return false;
10358
10356
  }
10359
10357
  function isWeakCachedResult(result) {
@@ -10507,6 +10505,27 @@ function sootsimHomeDir() {
10507
10505
  if (override && override.length > 0) return import_node_path.default.resolve(override);
10508
10506
  return import_node_path.default.join((0, import_node_os.homedir)(), ".sootsim");
10509
10507
  }
10508
+ function isSootsimDevCheckout() {
10509
+ if (process.env.SOOTSIM_FORCE_DAEMON_INSTALL === "1") return false;
10510
+ const env = process.env.SOOTSIM_DEV;
10511
+ if (env === "1" || env === "true") return true;
10512
+ if (env === "0" || env === "false") return false;
10513
+ const argv1 = process.argv[1];
10514
+ if (!argv1) return false;
10515
+ try {
10516
+ const real = import_node_fs2.default.realpathSync(argv1);
10517
+ return real.includes(`${import_node_path.default.sep}packages${import_node_path.default.sep}sootsim${import_node_path.default.sep}`);
10518
+ } catch {
10519
+ return false;
10520
+ }
10521
+ }
10522
+ function isDevWorkstation() {
10523
+ if (process.env.SOOTSIM_FORCE_DAEMON_INSTALL === "1") return false;
10524
+ return process.env.IS_TAMAGUI_DEV === "1";
10525
+ }
10526
+ function shouldSkipPersistentDaemon() {
10527
+ return isSootsimDevCheckout() || isDevWorkstation();
10528
+ }
10510
10529
  function runtimesDir() {
10511
10530
  return import_node_path.default.join(sootsimHomeDir(), "runtimes");
10512
10531
  }
@@ -10531,6 +10550,9 @@ function cacheDir() {
10531
10550
  function daemonLockfilePath() {
10532
10551
  return import_node_path.default.join(sootsimHomeDir(), DAEMON_LOCKFILE);
10533
10552
  }
10553
+ function devBridgeLockfilePath() {
10554
+ return import_node_path.default.join(sootsimHomeDir(), DEV_BRIDGE_LOCKFILE);
10555
+ }
10534
10556
  function configFilePath() {
10535
10557
  return import_node_path.default.join(sootsimHomeDir(), CONFIG_FILE);
10536
10558
  }
@@ -10636,6 +10658,25 @@ function readDaemonLockfile() {
10636
10658
  return null;
10637
10659
  }
10638
10660
  }
10661
+ function readDevBridgeLockfile() {
10662
+ try {
10663
+ const fd = import_node_fs2.default.openSync(devBridgeLockfilePath(), "r");
10664
+ try {
10665
+ const buf = Buffer.alloc(DAEMON_LOCKFILE_MAX_BYTES);
10666
+ const bytesRead = import_node_fs2.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
10667
+ const raw = buf.subarray(0, bytesRead).toString("utf8");
10668
+ const parsed = JSON.parse(raw);
10669
+ if (parsed && parsed.schema === 1 && parsed.source === "vite-dev" && typeof parsed.pid === "number" && typeof parsed.bridgePort === "number" && typeof parsed.runtimePort === "number" && typeof parsed.cwd === "string" && typeof parsed.startedAt === "number" && typeof parsed.heartbeatAt === "number") {
10670
+ return parsed;
10671
+ }
10672
+ return null;
10673
+ } finally {
10674
+ import_node_fs2.default.closeSync(fd);
10675
+ }
10676
+ } catch {
10677
+ return null;
10678
+ }
10679
+ }
10639
10680
  function isDaemonLockfileFresh(lock, now = Date.now()) {
10640
10681
  if (!lock) return false;
10641
10682
  if (now - lock.heartbeatAt > DAEMON_HEARTBEAT_STALE_MS) return false;
@@ -10646,6 +10687,16 @@ function isDaemonLockfileFresh(lock, now = Date.now()) {
10646
10687
  return false;
10647
10688
  }
10648
10689
  }
10690
+ function isDevBridgeLockfileFresh(lock, now = Date.now()) {
10691
+ if (!lock) return false;
10692
+ if (now - lock.heartbeatAt > DAEMON_HEARTBEAT_STALE_MS) return false;
10693
+ try {
10694
+ process.kill(lock.pid, 0);
10695
+ return true;
10696
+ } catch {
10697
+ return false;
10698
+ }
10699
+ }
10649
10700
  function writeDaemonLockfile(data) {
10650
10701
  ensureSootsimHome();
10651
10702
  const tmp = `${daemonLockfilePath()}.tmp`;
@@ -10653,6 +10704,13 @@ function writeDaemonLockfile(data) {
10653
10704
  `, "utf8");
10654
10705
  import_node_fs2.default.renameSync(tmp, daemonLockfilePath());
10655
10706
  }
10707
+ function writeDevBridgeLockfile(data) {
10708
+ ensureSootsimHome();
10709
+ const tmp = `${devBridgeLockfilePath()}.tmp`;
10710
+ import_node_fs2.default.writeFileSync(tmp, `${JSON.stringify(data, null, 2)}
10711
+ `, "utf8");
10712
+ import_node_fs2.default.renameSync(tmp, devBridgeLockfilePath());
10713
+ }
10656
10714
  function claimDaemonLockfile(data) {
10657
10715
  ensureSootsimHome();
10658
10716
  const existing = readDaemonLockfile();
@@ -10668,7 +10726,13 @@ function removeDaemonLockfile() {
10668
10726
  } catch {
10669
10727
  }
10670
10728
  }
10671
- var import_node_fs2, import_node_os, import_node_path, SOOTSIM_HOME_ENV, ACTIVE_RUNTIME_FILE, DAEMON_LOCKFILE, CONFIG_FILE, DAEMON_HEARTBEAT_STALE_MS, DAEMON_LOCKFILE_MAX_BYTES;
10729
+ function removeDevBridgeLockfile() {
10730
+ try {
10731
+ import_node_fs2.default.unlinkSync(devBridgeLockfilePath());
10732
+ } catch {
10733
+ }
10734
+ }
10735
+ var import_node_fs2, import_node_os, import_node_path, SOOTSIM_HOME_ENV, ACTIVE_RUNTIME_FILE, DAEMON_LOCKFILE, DEV_BRIDGE_LOCKFILE, CONFIG_FILE, DAEMON_HEARTBEAT_STALE_MS, DAEMON_LOCKFILE_MAX_BYTES;
10672
10736
  var init_home_paths = __esm({
10673
10737
  "src/home-paths.ts"() {
10674
10738
  "use strict";
@@ -10678,6 +10742,7 @@ var init_home_paths = __esm({
10678
10742
  SOOTSIM_HOME_ENV = "SOOTSIM_HOME";
10679
10743
  ACTIVE_RUNTIME_FILE = "active";
10680
10744
  DAEMON_LOCKFILE = "daemon.json";
10745
+ DEV_BRIDGE_LOCKFILE = "dev-bridge.json";
10681
10746
  CONFIG_FILE = "config.json";
10682
10747
  DAEMON_HEARTBEAT_STALE_MS = 3e4;
10683
10748
  DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
@@ -12860,10 +12925,12 @@ var init_bridge_host = __esm({
12860
12925
  maxConcurrentAutomationSims;
12861
12926
  automationSimActiveGraceMs;
12862
12927
  shouldWriteLockfile;
12928
+ shouldWriteDevLockfile;
12863
12929
  sootbeanOrigin = null;
12864
12930
  effectivePort = 0;
12865
12931
  startedAt = 0;
12866
12932
  heartbeatTimer = null;
12933
+ devHeartbeatTimer = null;
12867
12934
  // ws-level heartbeat: sims that hang up uncleanly (page navigated, network
12868
12935
  // dropped, sim crashed) leave their server-side WebSocket sitting "open"
12869
12936
  // forever. ping every WS_HEARTBEAT_INTERVAL_MS; if the previous round's
@@ -12890,6 +12957,7 @@ var init_bridge_host = __esm({
12890
12957
  this.preferredPort = opts.port || DEFAULT_SOOTSIM_BRIDGE_PORT;
12891
12958
  this.port = this.preferredPort;
12892
12959
  this.shouldWriteLockfile = opts.writeLockfile === true;
12960
+ this.shouldWriteDevLockfile = opts.writeDevLockfile === true;
12893
12961
  this.portFallbackCount = Math.max(1, opts.portFallbackCount ?? 10);
12894
12962
  this.openUrlHandler = opts.openUrl;
12895
12963
  this.agentHost = new AgentHost({ getExcludePorts: opts.agentScanExcludes });
@@ -13407,7 +13475,7 @@ var init_bridge_host = __esm({
13407
13475
  });
13408
13476
  });
13409
13477
  }
13410
- /** after a successful bind: start the cli idle sweep, write the daemon
13478
+ /** after a successful bind: start the cli idle sweep, write the daemon/dev
13411
13479
  * lockfile (if this host owns it), seed the agent host, kick off the
13412
13480
  * heartbeat loop. idempotent across rebinds because close() tears down
13413
13481
  * every timer and the lockfile. */
@@ -13449,6 +13517,23 @@ var init_bridge_host = __esm({
13449
13517
  this.heartbeatTimer.unref();
13450
13518
  this.startRuntimeUpdater();
13451
13519
  }
13520
+ if (this.shouldWriteDevLockfile) {
13521
+ try {
13522
+ this.writeDevLockfileSnapshot();
13523
+ } catch (err) {
13524
+ process.stderr.write(
13525
+ `ws bridge failed to write dev bridge lockfile: ${String(err)}
13526
+ `
13527
+ );
13528
+ }
13529
+ this.devHeartbeatTimer = setInterval(() => {
13530
+ try {
13531
+ this.writeDevLockfileSnapshot();
13532
+ } catch {
13533
+ }
13534
+ }, DAEMON_HEARTBEAT_INTERVAL_MS);
13535
+ this.devHeartbeatTimer.unref();
13536
+ }
13452
13537
  void this.agentHost.seedOnBoot();
13453
13538
  }
13454
13539
  bootstrapping = true;
@@ -13466,9 +13551,25 @@ var init_bridge_host = __esm({
13466
13551
  bootstrapping: this.bootstrapping
13467
13552
  };
13468
13553
  }
13554
+ buildDevLockfileSnapshot() {
13555
+ return {
13556
+ schema: 1,
13557
+ pid: process.pid,
13558
+ platform: process.platform,
13559
+ bridgePort: this.effectivePort,
13560
+ runtimePort: this.effectivePort,
13561
+ cwd: process.cwd(),
13562
+ startedAt: this.startedAt,
13563
+ heartbeatAt: Date.now(),
13564
+ source: "vite-dev"
13565
+ };
13566
+ }
13469
13567
  writeLockfileSnapshot() {
13470
13568
  writeDaemonLockfile(this.buildLockfileSnapshot());
13471
13569
  }
13570
+ writeDevLockfileSnapshot() {
13571
+ writeDevBridgeLockfile(this.buildDevLockfileSnapshot());
13572
+ }
13472
13573
  refreshActiveRuntime() {
13473
13574
  this.activeRuntimeVersion = readActiveRuntime();
13474
13575
  this.activeRuntimeDirPath = activeRuntimeDir();
@@ -13704,6 +13805,7 @@ var init_bridge_host = __esm({
13704
13805
  bridgePort: this.effectivePort,
13705
13806
  runtimePort: this.effectivePort,
13706
13807
  activeRuntime: this.activeRuntimeVersion,
13808
+ bridgeSource: this.shouldWriteDevLockfile ? "vite-dev" : this.shouldWriteLockfile ? "daemon" : "embedded",
13707
13809
  startedAt: this.startedAt,
13708
13810
  uptimeMs: this.startedAt > 0 ? Date.now() - this.startedAt : 0
13709
13811
  })
@@ -14085,6 +14187,10 @@ var init_bridge_host = __esm({
14085
14187
  clearInterval(this.heartbeatTimer);
14086
14188
  this.heartbeatTimer = null;
14087
14189
  }
14190
+ if (this.devHeartbeatTimer) {
14191
+ clearInterval(this.devHeartbeatTimer);
14192
+ this.devHeartbeatTimer = null;
14193
+ }
14088
14194
  if (this.wsHeartbeatTimer) {
14089
14195
  clearInterval(this.wsHeartbeatTimer);
14090
14196
  this.wsHeartbeatTimer = null;
@@ -14099,6 +14205,12 @@ var init_bridge_host = __esm({
14099
14205
  } catch {
14100
14206
  }
14101
14207
  }
14208
+ if (this.shouldWriteDevLockfile) {
14209
+ try {
14210
+ removeDevBridgeLockfile();
14211
+ } catch {
14212
+ }
14213
+ }
14102
14214
  this.effectivePort = 0;
14103
14215
  this.startedAt = 0;
14104
14216
  this.agentHost.close();
@@ -14708,6 +14820,10 @@ __export(ws_bridge_exports, {
14708
14820
  resolveDefaultBridgePort: () => resolveDefaultBridgePort
14709
14821
  });
14710
14822
  function resolveDefaultBridgePort() {
14823
+ if (shouldSkipPersistentDaemon()) {
14824
+ const dev = readDevBridgeLockfile();
14825
+ if (dev && isDevBridgeLockfileFresh(dev)) return dev.bridgePort;
14826
+ }
14711
14827
  const lock = readDaemonLockfile();
14712
14828
  if (lock && isDaemonLockfileFresh(lock)) return lock.bridgePort;
14713
14829
  return DEFAULT_SOOTSIM_BRIDGE_PORT;
@@ -17986,7 +18102,7 @@ var skill = {
17986
18102
  const { chromium } = await import("playwright");
17987
18103
  const path9 = await import("path");
17988
18104
  const fs9 = await import("fs");
17989
- const browser = await chromium.launch({ headless: true });
18105
+ const browser = await chromium.launch({ channel: "chrome", headless: true });
17990
18106
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
17991
18107
  try {
17992
18108
  await page.goto(context.url, { waitUntil: "networkidle" });
@@ -18161,7 +18277,7 @@ var skill3 = {
18161
18277
  const { chromium } = await import("playwright");
18162
18278
  const path9 = await import("path");
18163
18279
  const fs9 = await import("fs");
18164
- const browser = await chromium.launch({ headless: true });
18280
+ const browser = await chromium.launch({ channel: "chrome", headless: true });
18165
18281
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
18166
18282
  try {
18167
18283
  await page.goto(context.url, { waitUntil: "networkidle" });
@@ -18220,7 +18336,7 @@ var skill4 = {
18220
18336
  const { chromium } = await import("playwright");
18221
18337
  const path9 = await import("path");
18222
18338
  const fs9 = await import("fs");
18223
- const browser = await chromium.launch({ headless: true });
18339
+ const browser = await chromium.launch({ channel: "chrome", headless: true });
18224
18340
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
18225
18341
  try {
18226
18342
  await page.goto(context.url, { waitUntil: "networkidle" });
@@ -18371,7 +18487,7 @@ var skill6 = {
18371
18487
  const { chromium } = await import("playwright");
18372
18488
  const path9 = await import("path");
18373
18489
  const fs9 = await import("fs");
18374
- const browser = await chromium.launch({ headless: true });
18490
+ const browser = await chromium.launch({ channel: "chrome", headless: true });
18375
18491
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
18376
18492
  try {
18377
18493
  await page.goto(context.url, { waitUntil: "networkidle" });
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.168 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.170 | (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;
@@ -74,7 +74,7 @@ function readActiveRuntime() {
74
74
  var DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
75
75
 
76
76
  // src/runtime-assets.ts
77
- var SOOTSIM_RUNTIME_MISSING_MESSAGE = "[sootsim] no engine runtime installed \u2014 run `sootsim setup-repo` in your project, or `sootsim runtime install`";
77
+ var SOOTSIM_RUNTIME_MISSING_MESSAGE = "[sootsim] no engine runtime installed \u2014 run `sootsim setup`, or `sootsim runtime install`";
78
78
  var MIME_TYPES = {
79
79
  ".js": "application/javascript",
80
80
  ".mjs": "application/javascript",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sootsim",
3
- "version": "0.1.168",
3
+ "version": "0.1.170",
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",
@@ -132,6 +132,7 @@
132
132
  "dist-cli/",
133
133
  "dist-lib/",
134
134
  "src/",
135
+ "skills/",
135
136
  "scripts/dev-server-scanner.ts",
136
137
  "scripts/optional-demo-registry.ts",
137
138
  "detox/",
@@ -556,15 +556,14 @@ export interface ScanOptions {
556
556
  }
557
557
 
558
558
  function isSootSelfServer(server: DiscoveredServer): boolean {
559
- const projectName = server.projectName?.trim().toLowerCase()
560
- if (projectName === 'soot' || projectName === 'sootsim') return true
561
-
562
559
  const bundleId = server.bundleId?.trim().toLowerCase()
563
- if (bundleId?.startsWith('dev.soot')) return true
560
+ if (bundleId?.startsWith('dev.sootsim.')) return true
564
561
 
565
562
  return false
566
563
  }
567
564
 
565
+ export const __isSootSelfServerForTests = isSootSelfServer
566
+
568
567
  // per-(port, pid) probe cache. as long as the same process still owns the
569
568
  // port, its signature endpoints can't have changed, so we return the cached
570
569
  // result without issuing any HTTP. negative results (null) are cached too,
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  // postinstall — best-effort runtime install after `npm i -g sootsim`.
3
3
  //
4
- // runs as a child of npm. failures here are non-fatal: any first invocation
5
- // of the CLI will retry the install via auto-bootstrap.
4
+ // runs as a child of npm. failures here are non-fatal; setup/open/runtime
5
+ // commands can install the runtime later.
6
6
  //
7
7
  // skipped when running as root via sudo: $HOME would be /root, but the user
8
8
  // who actually wants the runtime probably isn't root. their first sootsim
@@ -11,8 +11,8 @@
11
11
  // reliability: npm preuninstall hooks are best-effort — they don't fire when
12
12
  // the package wasn't installed by npm (yarn/bun/pnpm have their own lifecycle
13
13
  // rules), and they don't run as part of `npm cache verify` cleanup or manual
14
- // dir removal. that's why we also document `sootsim daemon uninstall` as the
15
- // manual fallback and show a hint pointing at it.
14
+ // dir removal. that's why `sootsim daemon uninstall` is also documented as
15
+ // the manual teardown path.
16
16
  //
17
17
  // strategy: spawn the bundled bin to run `daemon uninstall` (single source of
18
18
  // truth — the same logic the user invokes manually). if that fails for any
@@ -73,17 +73,15 @@ function rawCleanup() {
73
73
  const home = sootsimHomeDir()
74
74
  if (process.platform === 'darwin') {
75
75
  safeSpawn('launchctl', ['bootout', `gui/${getuid()}/dev.sootsim.daemon`])
76
- safeSpawn('launchctl', ['bootout', `gui/${getuid()}/dev.sootsim.server`])
77
76
  safeRemove(path.join(os.homedir(), 'Library/LaunchAgents/dev.sootsim.daemon.plist'))
78
- safeRemove(path.join(os.homedir(), 'Library/LaunchAgents/dev.sootsim.server.plist'))
79
77
  safeRemove(path.join(os.homedir(), 'Library/Logs/sootsim'), {
80
78
  recursive: true,
81
79
  })
82
80
  } else if (process.platform === 'linux') {
83
- safeSpawn('systemctl', ['--user', 'disable', '--now', 'sootsim-server'])
81
+ safeSpawn('systemctl', ['--user', 'disable', '--now', 'sootsim-daemon'])
84
82
  safeSpawn('systemctl', ['--user', 'daemon-reload'])
85
- safeSpawn('systemctl', ['--user', 'reset-failed', 'sootsim-server'])
86
- safeRemove(path.join(os.homedir(), '.config/systemd/user/sootsim-server.service'))
83
+ safeSpawn('systemctl', ['--user', 'reset-failed', 'sootsim-daemon'])
84
+ safeRemove(path.join(os.homedir(), '.config/systemd/user/sootsim-daemon.service'))
87
85
  safeRemove(path.join(os.homedir(), '.local/state/sootsim'), { recursive: true })
88
86
  }
89
87
  // ~/.sootsim is the same on every platform; honor $SOOTSIM_HOME.