rnxsim 0.1.354 → 0.1.356

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 (179) hide show
  1. package/cli/bridge-flow-runner.ts +117 -75
  2. package/cli/commands/inspect/settling.ts +9 -2
  3. package/cli/commands/maestro.ts +9 -4
  4. package/cli/outbound-endpoints.ts +1 -1
  5. package/detox/index.ts +144 -74
  6. package/detox/proof-frame.cjs +107 -0
  7. package/dist-cli/bin.js +5 -5
  8. package/dist-cli/chunks/{agent-FB7RPXO6.js → agent-RHSVLLYV.js} +2 -2
  9. package/dist-cli/chunks/{agent-wrapper-LFU3XEIG.js → agent-wrapper-76J2FUFC.js} +2 -2
  10. package/dist-cli/chunks/{app-fonts-FK6SETRG.js → app-fonts-NXSVJTJO.js} +2 -2
  11. package/dist-cli/chunks/{assert-3KQYZDDK.js → assert-2EYNC3CJ.js} +2 -2
  12. package/dist-cli/chunks/{auth-RFE3J27C.js → auth-BPTC5SFR.js} +2 -2
  13. package/dist-cli/chunks/{beta-XVY4WOYH.js → beta-SSB7KYRA.js} +2 -2
  14. package/dist-cli/chunks/{camera-JROBX5GM.js → camera-VVTXBQXD.js} +2 -2
  15. package/dist-cli/chunks/{chunk-YIUIFZAE.js → chunk-2UIMQVMQ.js} +2 -2
  16. package/dist-cli/chunks/{chunk-B7OMSJXC.js → chunk-3OCUYKVX.js} +2 -2
  17. package/dist-cli/chunks/{chunk-ZNABCRWX.js → chunk-3QQFGK3A.js} +2 -2
  18. package/dist-cli/chunks/{chunk-3QLERZYJ.js → chunk-3SYKCLCM.js} +2 -2
  19. package/dist-cli/chunks/{chunk-BNXXNT3I.js → chunk-4HQXS5PW.js} +2 -2
  20. package/dist-cli/chunks/{chunk-P4GCLNFM.js → chunk-4V6JMAXO.js} +2 -2
  21. package/dist-cli/chunks/{chunk-SLD2EMLZ.js → chunk-5AF3BFLN.js} +2 -2
  22. package/dist-cli/chunks/{chunk-UI2IFVHB.js → chunk-5AKKSWL5.js} +1 -1
  23. package/dist-cli/chunks/{chunk-THFM2CFT.js → chunk-5DAVGCVR.js} +1 -1
  24. package/dist-cli/chunks/{chunk-CKKDXTKV.js → chunk-6CGOQKVQ.js} +1 -1
  25. package/dist-cli/chunks/{chunk-766UIGCS.js → chunk-6TGSJGCM.js} +2 -2
  26. package/dist-cli/chunks/{chunk-ATQPDEED.js → chunk-6TWYMJCB.js} +2 -2
  27. package/dist-cli/chunks/{chunk-LRVL5MAX.js → chunk-7E22W7XX.js} +1 -1
  28. package/dist-cli/chunks/{chunk-CUK6Y2RR.js → chunk-7EAA32OO.js} +2 -2
  29. package/dist-cli/chunks/{chunk-UX6D4X6B.js → chunk-A2F5B2AB.js} +2 -2
  30. package/dist-cli/chunks/{chunk-HUU7ZUQK.js → chunk-AA7PHU2M.js} +2 -2
  31. package/dist-cli/chunks/{chunk-3RW6W3ZO.js → chunk-BMMSSIRU.js} +1 -1
  32. package/dist-cli/chunks/{chunk-JT4IMNCO.js → chunk-BNZHWG6Z.js} +2 -2
  33. package/dist-cli/chunks/{chunk-UAYXEP74.js → chunk-BXT37FPN.js} +1 -1
  34. package/dist-cli/chunks/{chunk-QQNNY43R.js → chunk-BZTXJUGV.js} +1 -1
  35. package/dist-cli/chunks/{chunk-ENPWD62S.js → chunk-CK4C6GPT.js} +2 -2
  36. package/dist-cli/chunks/{chunk-ZJUFI3R7.js → chunk-DRHNOXRS.js} +1 -1
  37. package/dist-cli/chunks/{chunk-MIK6LMG4.js → chunk-E5ALNGXA.js} +1 -1
  38. package/dist-cli/chunks/{chunk-FPH4TYZO.js → chunk-E7DVCUK4.js} +3 -3
  39. package/dist-cli/chunks/{chunk-7WANPS3W.js → chunk-EVQNKPUK.js} +2 -2
  40. package/dist-cli/chunks/{chunk-QRYTCPNO.js → chunk-FAUFZBRY.js} +2 -2
  41. package/dist-cli/chunks/chunk-FVKAF4VB.js +535 -0
  42. package/dist-cli/chunks/{chunk-JWXAXCC6.js → chunk-FWBQKEAA.js} +2 -2
  43. package/dist-cli/chunks/{chunk-IGV4KCCM.js → chunk-G2SHGCDI.js} +2 -2
  44. package/dist-cli/chunks/{chunk-PHIYWV44.js → chunk-GM6YYN6P.js} +2 -2
  45. package/dist-cli/chunks/{chunk-UVIWE3LD.js → chunk-I3G6YW6L.js} +1 -1
  46. package/dist-cli/chunks/{chunk-HIYCRDUP.js → chunk-IUQL37TT.js} +2 -2
  47. package/dist-cli/chunks/{chunk-LCPZNPIB.js → chunk-JU3ISZ7X.js} +1 -1
  48. package/dist-cli/chunks/{chunk-4OS3SXPZ.js → chunk-NPH2KUL6.js} +2 -2
  49. package/dist-cli/chunks/{chunk-77CBLMD4.js → chunk-NSEPQLZF.js} +1 -1
  50. package/dist-cli/chunks/{chunk-OKFSCCFC.js → chunk-OUMGSDHQ.js} +1 -1
  51. package/dist-cli/chunks/{chunk-IUL2WUWW.js → chunk-P5F5PM6C.js} +2 -2
  52. package/dist-cli/chunks/{chunk-GNKXRXND.js → chunk-RBQUFMLX.js} +2 -2
  53. package/dist-cli/chunks/{chunk-Y4GUWO3X.js → chunk-RFSFQUUJ.js} +1 -1
  54. package/dist-cli/chunks/{chunk-TJRKLRNP.js → chunk-RQZCBNCD.js} +1 -1
  55. package/dist-cli/chunks/{chunk-LC77IVGY.js → chunk-SZD4NAQR.js} +2 -2
  56. package/dist-cli/chunks/{chunk-37S36DFW.js → chunk-T33T5MW2.js} +1 -1
  57. package/dist-cli/chunks/{chunk-4AQCDL24.js → chunk-TLA6GLYI.js} +2 -2
  58. package/dist-cli/chunks/{chunk-JT435OOM.js → chunk-TV5LN34R.js} +2 -2
  59. package/dist-cli/chunks/{chunk-EWPX6LEN.js → chunk-UC6Y77PK.js} +2 -2
  60. package/dist-cli/chunks/{chunk-IICFLREN.js → chunk-UUD5NLLB.js} +1 -1
  61. package/dist-cli/chunks/{chunk-GYGDIT5V.js → chunk-VIEN2LIY.js} +2 -2
  62. package/dist-cli/chunks/{chunk-X2DJK3TB.js → chunk-VSADIZVW.js} +2 -2
  63. package/dist-cli/chunks/{chunk-JXNR2KAB.js → chunk-VZKPDDYL.js} +2 -2
  64. package/dist-cli/chunks/{chunk-YXBNGSG6.js → chunk-X2YH3SPS.js} +1 -1
  65. package/dist-cli/chunks/{chunk-LETVUC6M.js → chunk-XJ2LMLUP.js} +1 -1
  66. package/dist-cli/chunks/{chunk-24DA3Y2Z.js → chunk-XMNBS5CX.js} +1 -1
  67. package/dist-cli/chunks/{chunk-JJOHJNUQ.js → chunk-XT6FA7AH.js} +2 -2
  68. package/dist-cli/chunks/chunk-Z6CATT5W.js +4 -0
  69. package/dist-cli/chunks/{chunk-N3CE6AZP.js → chunk-ZK67ALEG.js} +2 -2
  70. package/dist-cli/chunks/{chunk-FEHHM2LV.js → chunk-ZME75NBJ.js} +13 -6
  71. package/dist-cli/chunks/{cleanup-F74ISXJC.js → cleanup-E7TDW64X.js} +2 -2
  72. package/dist-cli/chunks/cli-version-HUIGZMTX.js +4 -0
  73. package/dist-cli/chunks/{compat-C3RGYGXL.js → compat-ST5BY7FP.js} +2 -2
  74. package/dist-cli/chunks/{config-CDY2RB7Q.js → config-Z5NEHXI7.js} +2 -2
  75. package/dist-cli/chunks/{control-J35HAFZA.js → control-JMDFMAHT.js} +2 -2
  76. package/dist-cli/chunks/daemon-VIL2M7RE.js +4 -0
  77. package/dist-cli/chunks/{debug-3P2DUTUQ.js → debug-DO2G2BA7.js} +3 -3
  78. package/dist-cli/chunks/{desktop-XIXW34VW.js → desktop-M3UETMNI.js} +3 -3
  79. package/dist-cli/chunks/{detox-KAKTJ4P4.js → detox-7JI56JTD.js} +2 -2
  80. package/dist-cli/chunks/{device-4MAWLZMR.js → device-YTRCB26J.js} +2 -2
  81. package/dist-cli/chunks/{diagnose-A3R7HUYA.js → diagnose-BJT3RXDI.js} +2 -2
  82. package/dist-cli/chunks/{disk-cleanup-5R7JYCO6.js → disk-cleanup-HWA4ATEL.js} +2 -2
  83. package/dist-cli/chunks/drivers-HIKMT3EH.js +4 -0
  84. package/dist-cli/chunks/{film-GY5U752Q.js → film-GLGYFHGZ.js} +3 -3
  85. package/dist-cli/chunks/flow-AJT2OYLT.js +4 -0
  86. package/dist-cli/chunks/help-DSDQRHN3.js +4 -0
  87. package/dist-cli/chunks/{hidden-runtime-alias-HSGN3GN4.js → hidden-runtime-alias-A4TMRHFA.js} +2 -2
  88. package/dist-cli/chunks/{home-paths-BIUN4CBO.js → home-paths-A2ANFZHA.js} +2 -2
  89. package/dist-cli/chunks/inspect-NXE6LUT6.js +4 -0
  90. package/dist-cli/chunks/install-desktop-DMTXQF3R.js +4 -0
  91. package/dist-cli/chunks/{login-WKNMS4GG.js → login-OWD44PHN.js} +2 -2
  92. package/dist-cli/chunks/{logout-6UFUOESK.js → logout-WV5QPIUW.js} +2 -2
  93. package/dist-cli/chunks/{maestro-SJGV7B3W.js → maestro-AQ342FXT.js} +18 -13
  94. package/dist-cli/chunks/{maestro-generate-PMF2LLKX.js → maestro-generate-AUTBK5QS.js} +3 -3
  95. package/dist-cli/chunks/{mode-MN7LZCLB.js → mode-XICLRQZH.js} +2 -2
  96. package/dist-cli/chunks/{optional-demo-registry-HFA27YSP.js → optional-demo-registry-FOXLAYLM.js} +2 -2
  97. package/dist-cli/chunks/{perf-XGANSJT3.js → perf-PUT7IITA.js} +2 -2
  98. package/dist-cli/chunks/{permissions-25UWEJKW.js → permissions-AHJWQPCL.js} +2 -2
  99. package/dist-cli/chunks/privacy-AYLEWFZX.js +4 -0
  100. package/dist-cli/chunks/{record-MA3AI752.js → record-V4MZ33XI.js} +3 -3
  101. package/dist-cli/chunks/{report-issue-4DTESWE2.js → report-issue-QBB54OJ5.js} +2 -2
  102. package/dist-cli/chunks/reset-BMGMOHRM.js +4 -0
  103. package/dist-cli/chunks/runtime-SYUM3ASK.js +4 -0
  104. package/dist-cli/chunks/{screenshot-command-JUXMWXS5.js → screenshot-command-PK54GDUY.js} +3 -3
  105. package/dist-cli/chunks/{screenshot-layers-DJF2E4PE.js → screenshot-layers-AQZK3GRM.js} +2 -2
  106. package/dist-cli/chunks/{screenshots-capture-UGZU5GOW.js → screenshots-capture-KXQDIF2S.js} +2 -2
  107. package/dist-cli/chunks/{serve-H7GNKJSM.js → serve-YPNVL33J.js} +2 -2
  108. package/dist-cli/chunks/setup-FM3JVRMY.js +4 -0
  109. package/dist-cli/chunks/{skills-4JGPOSFE.js → skills-4CBIW5IP.js} +2 -2
  110. package/dist-cli/chunks/{state-DEAQFKVP.js → state-AWM3LRRR.js} +2 -2
  111. package/dist-cli/chunks/{storage-Y6F5NTGH.js → storage-S2LC3T7Q.js} +2 -2
  112. package/dist-cli/chunks/store-SZX3GXCL.js +4 -0
  113. package/dist-cli/chunks/telemetry-ANUHW6KD.js +4 -0
  114. package/dist-cli/chunks/{timeline-HOHYYDOC.js → timeline-4AWI6M2T.js} +2 -2
  115. package/dist-cli/chunks/{upgrade-QF5YHLSG.js → upgrade-WSYVILOP.js} +2 -2
  116. package/dist-cli/chunks/upload-U2KPYBGD.js +4 -0
  117. package/dist-cli/chunks/{version-PDCKYJLB.js → version-XE4ZTCON.js} +2 -2
  118. package/dist-cli/chunks/{web-C5EUAFFW.js → web-ZS6L2NLF.js} +2 -2
  119. package/dist-cli/chunks/welcome-UE273JKY.js +5 -0
  120. package/dist-cli/chunks/{what-happened-L56ZFIMJ.js → what-happened-6AHCKADV.js} +2 -2
  121. package/dist-lib/agent-daemon-client.cjs +1 -1
  122. package/dist-lib/agent-events.cjs +1 -1
  123. package/dist-lib/agent-identity.cjs +1 -1
  124. package/dist-lib/agent-sessions.cjs +1 -1
  125. package/dist-lib/attached-projects.cjs +1 -1
  126. package/dist-lib/auth/shared-session.cjs +1 -1
  127. package/dist-lib/backend-origin.cjs +1 -1
  128. package/dist-lib/beta.cjs +1 -1
  129. package/dist-lib/beta.mjs +1 -1
  130. package/dist-lib/bridge-constants.cjs +1 -1
  131. package/dist-lib/bridge-contract.cjs +1 -1
  132. package/dist-lib/cli-constants.cjs +1 -1
  133. package/dist-lib/config.cjs +1 -1
  134. package/dist-lib/detox/index.cjs +196 -54
  135. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  136. package/dist-lib/home-paths.cjs +1 -1
  137. package/dist-lib/host/bridge-host.cjs +1 -1
  138. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  139. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  140. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  141. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  142. package/dist-lib/host/websocket-proxy.cjs +1 -1
  143. package/dist-lib/index.cjs +10 -3
  144. package/dist-lib/jump-to-source-babel.cjs +1 -1
  145. package/dist-lib/menu.cjs +1 -1
  146. package/dist-lib/menu.mjs +1 -1
  147. package/dist-lib/metro-production-bundle.cjs +1 -1
  148. package/dist-lib/metro-production-bundle.mjs +1 -1
  149. package/dist-lib/metro.cjs +1 -1
  150. package/dist-lib/profiles.cjs +1 -1
  151. package/dist-lib/public-brand.cjs +1 -1
  152. package/dist-lib/react-native-host-modules.cjs +1 -1
  153. package/dist-lib/react-native-host-modules.mjs +1 -1
  154. package/dist-lib/render-mode.cjs +1 -1
  155. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  156. package/dist-lib/sdk.cjs +10 -3
  157. package/dist-lib/sdk.mjs +10 -3
  158. package/dist-lib/skills.cjs +4778 -211
  159. package/dist-lib/vite.cjs +1 -1
  160. package/package.json +1 -1
  161. package/skills/rnx-test/SKILL.md +6 -2
  162. package/src/bridge-contract.ts +8 -2
  163. package/dist-cli/chunks/chunk-BAWV2UEF.js +0 -543
  164. package/dist-cli/chunks/chunk-YATZ7U4S.js +0 -4
  165. package/dist-cli/chunks/cli-version-VSDCFXXN.js +0 -4
  166. package/dist-cli/chunks/daemon-DLLEODJY.js +0 -4
  167. package/dist-cli/chunks/drivers-BB3BRKDS.js +0 -4
  168. package/dist-cli/chunks/flow-ALMSRBVL.js +0 -4
  169. package/dist-cli/chunks/help-3ZL7MRUX.js +0 -4
  170. package/dist-cli/chunks/inspect-RCU7XVAO.js +0 -4
  171. package/dist-cli/chunks/install-desktop-LYVKLTCU.js +0 -4
  172. package/dist-cli/chunks/privacy-SIDMP5EF.js +0 -4
  173. package/dist-cli/chunks/reset-GPHG5XN3.js +0 -4
  174. package/dist-cli/chunks/runtime-VOEIOODA.js +0 -4
  175. package/dist-cli/chunks/setup-G2WYLPM6.js +0 -4
  176. package/dist-cli/chunks/store-3EQT7VU6.js +0 -4
  177. package/dist-cli/chunks/telemetry-FANCQHKG.js +0 -4
  178. package/dist-cli/chunks/upload-QKJHFAX7.js +0 -4
  179. package/dist-cli/chunks/welcome-3CQ2GE4F.js +0 -5
package/detox/index.ts CHANGED
@@ -6,6 +6,7 @@ import * as fs from 'fs'
6
6
  import * as path from 'path'
7
7
  import { chromium } from 'playwright'
8
8
  import { launchReapedChromeScoped } from '../../../scripts/lib/reap-browser'
9
+ import { pollUntil } from '../src/poll-until'
9
10
  import { createExpect, createWaitFor } from './expectations'
10
11
  import {
11
12
  dispatchTwoFingerGesture,
@@ -22,6 +23,7 @@ import {
22
23
  type MotionChangeDefinition,
23
24
  type MotionChangeMeasurement,
24
25
  } from './motion-change.cjs'
26
+ import { REQUIRED_IDENTICAL_PROOF_FRAMES, framesIdentical } from './proof-frame.cjs'
25
27
  import type { SootSimElement } from './element-types'
26
28
  import type { Browser, BrowserContext, Page } from 'playwright'
27
29
  import type { SootsimEventMap, SootsimEventName } from 'sootsim-engine/sootsim-event'
@@ -42,6 +44,7 @@ let _reapBrowserNow: (() => void) | null = null
42
44
  let _context: BrowserContext | null = null
43
45
  let _page: Page | null = null
44
46
  let _synchronizationEnabled = false
47
+ let _suspendedAppId: string | null = null
45
48
  const pageDiagnostics = new WeakMap<Page, string[]>()
46
49
 
47
50
  const STATUS_BAR_OVERRIDE_EVENT = 'sootsim:statusBarOverride'
@@ -339,9 +342,14 @@ async function closeBrowser() {
339
342
  }
340
343
  }
341
344
 
342
- export async function waitForSootsimIdle(page: Page, maxMs = 3000): Promise<void> {
345
+ export async function waitForSootsimIdle(
346
+ page: Page,
347
+ maxMs = 3000,
348
+ strict = false,
349
+ ): Promise<void> {
343
350
  const result = await page.evaluate(
344
- async ({ maxMs }) => {
351
+ async ({ maxMs, strict }) => {
352
+ const start = Date.now()
345
353
  let transitionError: string | null = null
346
354
  try {
347
355
  const waitForScreenTransitions = (window as any).__sootsimTest
@@ -352,13 +360,6 @@ export async function waitForSootsimIdle(page: Page, maxMs = 3000): Promise<void
352
360
  settleMs: 48,
353
361
  startWindowMs: 600,
354
362
  })
355
- if (
356
- transitionResult?.started === true &&
357
- transitionResult.settled === true &&
358
- transitionResult.timedOut !== true
359
- ) {
360
- return { settled: true, elapsed: transitionResult.waitedMs ?? 0 }
361
- }
362
363
  if (transitionResult?.timedOut) {
363
364
  return {
364
365
  settled: false,
@@ -371,7 +372,6 @@ export async function waitForSootsimIdle(page: Page, maxMs = 3000): Promise<void
371
372
  transitionError = error instanceof Error ? error.message : String(error)
372
373
  }
373
374
 
374
- const start = Date.now()
375
375
  const deadline = start + maxMs
376
376
  const pollMs = 50
377
377
  const requiredStablePolls = 3
@@ -388,6 +388,28 @@ export async function waitForSootsimIdle(page: Page, maxMs = 3000): Promise<void
388
388
  const readSnapshot = async () => {
389
389
  const root = (window as any).__sootsimRoot
390
390
  const layout: number[] = []
391
+ let animating = false
392
+ let auxSurfaceDebug: unknown = null
393
+ let layoutDirty = false
394
+ let renderStatsAvailable = false
395
+ if (strict) {
396
+ try {
397
+ const renderHost: unknown = Reflect.get(window, '__sootsimRenderHost')
398
+ const queryStats =
399
+ typeof renderHost === 'object' && renderHost !== null
400
+ ? Reflect.get(renderHost, 'queryStats')
401
+ : null
402
+ const stats =
403
+ typeof queryStats === 'function' ? await queryStats.call(renderHost) : null
404
+ renderStatsAvailable = !!stats
405
+ auxSurfaceDebug = stats?.auxSurfaceDebug ?? null
406
+ animating =
407
+ stats?.hasActiveAnims === true ||
408
+ stats?.hasActiveNativeAnimations === true ||
409
+ stats?.hasPendingAnimationFrames === true
410
+ layoutDirty = stats?.layoutDirty === true && stats?.renderRequested === true
411
+ } catch {}
412
+ }
391
413
  if (root) {
392
414
  const walk = (node: any) => {
393
415
  if (node.layout && node.layout.width > 0) {
@@ -402,20 +424,33 @@ export async function waitForSootsimIdle(page: Page, maxMs = 3000): Promise<void
402
424
  }
403
425
  walk(root)
404
426
  }
405
- return layout
427
+ return {
428
+ animating,
429
+ auxSurfaceDebug,
430
+ layout,
431
+ layoutDirty,
432
+ renderStatsAvailable,
433
+ }
406
434
  }
407
435
 
408
436
  let stableLayout: number[] | null = null
409
437
  let stable = 0
438
+ let lastSnapshot: Awaited<ReturnType<typeof readSnapshot>> | null = null
410
439
  while (Date.now() < deadline) {
411
- const layout = await readSnapshot()
412
- if (isLayoutStable(stableLayout, layout)) {
440
+ const snapshot = await readSnapshot()
441
+ lastSnapshot = snapshot
442
+ if (
443
+ (!strict || snapshot.renderStatsAvailable) &&
444
+ !snapshot.animating &&
445
+ !snapshot.layoutDirty &&
446
+ isLayoutStable(stableLayout, snapshot.layout)
447
+ ) {
413
448
  stable++
414
449
  if (stable >= requiredStablePolls) {
415
450
  return { settled: true, elapsed: Date.now() - start }
416
451
  }
417
452
  } else {
418
- stableLayout = layout
453
+ stableLayout = snapshot.layout
419
454
  stable = 0
420
455
  }
421
456
  await sleep(pollMs)
@@ -425,10 +460,12 @@ export async function waitForSootsimIdle(page: Page, maxMs = 3000): Promise<void
425
460
  elapsed: Date.now() - start,
426
461
  reason: transitionError
427
462
  ? `layout fallback after screen transition wait failed: ${transitionError}`
428
- : 'layout fallback',
463
+ : strict
464
+ ? `strict idle state unavailable: renderStats=${lastSnapshot?.renderStatsAvailable === true} animating=${lastSnapshot?.animating === true} layoutDirty=${lastSnapshot?.layoutDirty === true} layoutNodes=${(lastSnapshot?.layout.length ?? 0) / 4} aux=${JSON.stringify(lastSnapshot?.auxSurfaceDebug)}`
465
+ : 'layout fallback',
429
466
  }
430
467
  },
431
- { maxMs },
468
+ { maxMs, strict },
432
469
  )
433
470
 
434
471
  if (!result?.settled) {
@@ -633,7 +670,7 @@ function writeFastScreenshotFrames<T extends FastScreenshotData>(
633
670
 
634
671
  // single-shot canvas capture — no frame-stability poll. used for multi-stage
635
672
  // animation captures where we explicitly want to sample mid-transition. the
636
- // usual captureSootsimPng polls until two consecutive frames are byte-equal
673
+ // usual captureSootsimPng requires three consecutive idle frames to be byte-equal
637
674
  // which is ideal for settled screenshots but blocks for the full timeout
638
675
  // while an animation is running.
639
676
  async function captureSootsimPngFast(opts?: {
@@ -661,62 +698,25 @@ async function captureSootsimPng(opts?: {
661
698
  crop?: { h: number; w: number; x: number; y: number }
662
699
  }) {
663
700
  const page = getPage()
664
- // frame-stability poll: capture twice with a gap > one tenant live-blur
665
- // push interval (~67ms) and accept only when both PNGs are byte-equal.
666
- // PNGs from canvas.toDataURL are deterministic for stable RGBA, so byte-
667
- // equal = pixel-equal. without this, the keyboard's blur stream and the
668
- // text-input cursor blink produce 1-12pp frame-to-frame variance in
669
- // captures fired blindly after a settle, which then drifts the published
670
- // proof manifest. matches the same poll in scripts/conformance-fast-iter.ts
671
- // so cron and publish lock onto the same stable frame.
672
- const result: {
673
- dataUrl: string
674
- stable: boolean
675
- attempts: number
676
- elapsedMs: number
677
- } = await page.evaluate(
678
- async (captureOpts) => {
679
- const screenshot = (window as { SootSim?: { bridges?: { screenshot?: unknown } } })
680
- .SootSim?.bridges?.screenshot as ((opts?: unknown) => Promise<string>) | undefined
681
- if (typeof screenshot !== 'function') {
682
- throw new Error('sootsim screenshot bridge is not installed')
683
- }
684
- const gapMs = 100
685
- const maxWaitMs = 8000
686
- const minAttempts = 3
687
- const t0 = Date.now()
688
- let prev = await screenshot(captureOpts)
689
- let attempts = 1
690
- while (attempts < minAttempts || Date.now() - t0 < maxWaitMs) {
691
- await new Promise((r) => setTimeout(r, gapMs))
692
- const next = await screenshot(captureOpts)
693
- attempts++
694
- if (next === prev) {
695
- return {
696
- dataUrl: next,
697
- stable: true,
698
- attempts,
699
- elapsedMs: Date.now() - t0,
700
- }
701
- }
702
- prev = next
703
- }
704
- return { dataUrl: prev, stable: false, attempts, elapsedMs: Date.now() - t0 }
705
- },
706
- {
707
- crop: opts?.crop,
708
- format: 'png',
709
- },
710
- )
711
- if (!result.dataUrl) {
712
- throw new Error('sootsim screenshot bridge returned an empty image')
713
- }
714
- if (!result.stable) {
715
- console.warn(
716
- `[sootsim-detox] screenshot did not stabilize after ${result.elapsedMs}ms (${result.attempts} captures); using last frame`,
717
- )
701
+ const deadline = Date.now() + 8000
702
+ let previous: Buffer | null = null
703
+ let identicalFrames = 1
704
+ let attempts = 0
705
+ while (Date.now() < deadline) {
706
+ await waitForSootsimIdle(page, Math.max(1, deadline - Date.now()), true)
707
+ const current = await captureSootsimPngFast(opts)
708
+ attempts++
709
+ if (framesIdentical(previous, current)) {
710
+ identicalFrames++
711
+ if (identicalFrames >= REQUIRED_IDENTICAL_PROOF_FRAMES) return current
712
+ } else {
713
+ identicalFrames = 1
714
+ }
715
+ previous = current
718
716
  }
719
- return decodePngDataUrl(result.dataUrl)
717
+ throw new Error(
718
+ `sootsim screenshot did not reach ${REQUIRED_IDENTICAL_PROOF_FRAMES} identical idle frames in ${attempts} captures`,
719
+ )
720
720
  }
721
721
 
722
722
  async function writeSootsimScreenshot(
@@ -892,8 +892,23 @@ function createSootSimElement(matcher: Matcher): SootSimElement {
892
892
 
893
893
  async replaceText(text: string) {
894
894
  const page = getPage()
895
- await focusElementForTextEntry(el)
896
895
  const node = await findNodeByMatcher(matcher)
896
+ if (
897
+ matcher.type === 'id' &&
898
+ typeof node?.nodeId === 'number' &&
899
+ node.nodeId >= 0x40000000
900
+ ) {
901
+ const replaced = await page.evaluate(
902
+ async ({ id, value }) => {
903
+ const mainShell = window.SootSim?.bridges?.mainShell
904
+ if (typeof mainShell?.callTestBridge !== 'function') return false
905
+ return mainShell.callTestBridge('replaceTextByTestId', id, value)
906
+ },
907
+ { id: matcher.value, value: text },
908
+ )
909
+ if (replaced === true) return
910
+ }
911
+ await focusElementForTextEntry(el)
897
912
  const value = typeof node?.text === 'string' ? node.text : ''
898
913
  for (let i = 0; i < value.length; i++) {
899
914
  await page.keyboard.press('Backspace')
@@ -1267,6 +1282,40 @@ export const device = {
1267
1282
  // toggled on an existing context.
1268
1283
  recordVideoDir?: string
1269
1284
  }) {
1285
+ if (
1286
+ _page &&
1287
+ opts?.newInstance === false &&
1288
+ !opts.delete &&
1289
+ !opts.recordVideoDir &&
1290
+ _suspendedAppId
1291
+ ) {
1292
+ const page = _page
1293
+ const appId = _suspendedAppId
1294
+ await page.evaluate(
1295
+ (id) => window.SootSim?.bridges?.mainShell?.launchApp?.(id),
1296
+ appId,
1297
+ )
1298
+ await pollUntil(
1299
+ () =>
1300
+ page.evaluate(async (id) => {
1301
+ const state = await window.SootSim?.bridges?.mainShell?.getState?.()
1302
+ return (
1303
+ state?.state === 'app' &&
1304
+ state.activeApp === id &&
1305
+ state.switcherPhase === 'idle'
1306
+ )
1307
+ }, appId),
1308
+ Boolean,
1309
+ {
1310
+ timeoutMs: 10000,
1311
+ label: `SootSim app ${appId} to resume`,
1312
+ },
1313
+ )
1314
+ _suspendedAppId = null
1315
+ await waitForSootsimTree(page, 10000)
1316
+ return
1317
+ }
1318
+
1270
1319
  if (!_browser) {
1271
1320
  // Conformance renders CanvasKit and must use the real platform GPU. The
1272
1321
  // bundled chromium_headless_shell has no GPU and silently falls back to
@@ -2237,7 +2286,28 @@ export const device = {
2237
2286
  },
2238
2287
 
2239
2288
  async sendToHome() {
2240
- // no-op
2289
+ const page = getPage()
2290
+ _suspendedAppId = await page.evaluate(async () => {
2291
+ const state = await window.SootSim?.bridges?.mainShell?.getState?.()
2292
+ const appId = state?.activeApp
2293
+ if (typeof appId !== 'string') {
2294
+ throw new Error(`cannot send an inactive SootSim app home`)
2295
+ }
2296
+ window.SootSim?.bridges?.mainShell?.goHome?.()
2297
+ return appId
2298
+ })
2299
+ await pollUntil(
2300
+ () =>
2301
+ page.evaluate(async () => {
2302
+ const state = await window.SootSim?.bridges?.mainShell?.getState?.()
2303
+ return state?.state === 'home' && state.switcherPhase === 'idle'
2304
+ }),
2305
+ Boolean,
2306
+ {
2307
+ timeoutMs: 10000,
2308
+ label: 'SootSim home transition',
2309
+ },
2310
+ )
2241
2311
  },
2242
2312
 
2243
2313
  // get direct access to the playwright page for advanced use
@@ -0,0 +1,107 @@
1
+ // proof captures reserve the top and bottom of a device frame for platform
2
+ // chrome. those pixels can be fully opaque while the app surface is blank or
3
+ // still fading in, so evidence density is measured only in the content band.
4
+ const PROOF_CONTENT_DEFINITION = Object.freeze({
5
+ channelThreshold: 24,
6
+ contentBandInsetFraction: 0.08,
7
+ minimumContentPercent: 0.005,
8
+ })
9
+
10
+ const REQUIRED_IDENTICAL_PROOF_FRAMES = 3
11
+
12
+ function framesIdentical(a, b) {
13
+ if (!a || !b || a.length !== b.length) return false
14
+ return a.equals(b)
15
+ }
16
+
17
+ function measureProofFrameContent(input) {
18
+ if (!input || typeof input !== 'object' || Array.isArray(input)) {
19
+ throw new Error('proof content measurement requires an input object')
20
+ }
21
+ const { data, width, height } = input
22
+ if (
23
+ !data ||
24
+ typeof data.length !== 'number' ||
25
+ !Number.isInteger(width) ||
26
+ !Number.isInteger(height) ||
27
+ width <= 0 ||
28
+ height <= 0 ||
29
+ data.length !== width * height * 4
30
+ ) {
31
+ throw new Error('proof content measurement needs RGBA pixels and dimensions')
32
+ }
33
+
34
+ const yStart = Math.floor(height * PROOF_CONTENT_DEFINITION.contentBandInsetFraction)
35
+ const yEnd = Math.ceil(
36
+ height * (1 - PROOF_CONTENT_DEFINITION.contentBandInsetFraction),
37
+ )
38
+ const bucketCounts = new Uint32Array(32 * 32 * 32)
39
+ let totalPixels = 0
40
+ for (let y = yStart; y < yEnd; y++) {
41
+ for (let x = 0; x < width; x++) {
42
+ const offset = (y * width + x) * 4
43
+ const bucket =
44
+ ((data[offset] >> 3) << 10) |
45
+ ((data[offset + 1] >> 3) << 5) |
46
+ (data[offset + 2] >> 3)
47
+ bucketCounts[bucket]++
48
+ totalPixels++
49
+ }
50
+ }
51
+
52
+ let dominantBucket = 0
53
+ for (let index = 1; index < bucketCounts.length; index++) {
54
+ if (bucketCounts[index] > bucketCounts[dominantBucket]) dominantBucket = index
55
+ }
56
+ const dominant = {
57
+ red: (((dominantBucket >> 10) & 31) << 3) + 4,
58
+ green: (((dominantBucket >> 5) & 31) << 3) + 4,
59
+ blue: ((dominantBucket & 31) << 3) + 4,
60
+ }
61
+
62
+ let contentPixels = 0
63
+ for (let y = yStart; y < yEnd; y++) {
64
+ for (let x = 0; x < width; x++) {
65
+ const offset = (y * width + x) * 4
66
+ if (
67
+ Math.max(
68
+ Math.abs(data[offset] - dominant.red),
69
+ Math.abs(data[offset + 1] - dominant.green),
70
+ Math.abs(data[offset + 2] - dominant.blue),
71
+ ) >= PROOF_CONTENT_DEFINITION.channelThreshold
72
+ ) {
73
+ contentPixels++
74
+ }
75
+ }
76
+ }
77
+
78
+ const contentPercent = (contentPixels / totalPixels) * 100
79
+ return {
80
+ contentPercent,
81
+ contentPixels,
82
+ dominant,
83
+ passedMinimum:
84
+ contentPercent >= PROOF_CONTENT_DEFINITION.minimumContentPercent,
85
+ totalPixels,
86
+ }
87
+ }
88
+
89
+ function settleDecision(previousPixels, currentFrame) {
90
+ if (!currentFrame) return { decision: 'continue', content: null }
91
+ const content = measureProofFrameContent(currentFrame)
92
+ if (!content.passedMinimum) {
93
+ return { decision: 'insufficient-content', content }
94
+ }
95
+ if (previousPixels && framesIdentical(previousPixels, currentFrame.data)) {
96
+ return { decision: 'identical', content }
97
+ }
98
+ return { decision: 'changed', content }
99
+ }
100
+
101
+ module.exports = {
102
+ PROOF_CONTENT_DEFINITION,
103
+ REQUIRED_IDENTICAL_PROOF_FRAMES,
104
+ framesIdentical,
105
+ measureProofFrameContent,
106
+ settleDecision,
107
+ }
package/dist-cli/bin.js CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- /*! rnx v0.1.354 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ /*! rnx v0.1.356 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
3
3
  import { createRequire as __sootsimCreateRequire } from 'node:module'
4
4
  var require = __sootsimCreateRequire(import.meta.url)
5
- import{a as g,b as f}from"./chunks/chunk-37S36DFW.js";import{a as m}from"./chunks/chunk-UI2IFVHB.js";import"./chunks/chunk-QQNNY43R.js";function A(a){let t=a instanceof Error?a.message:String(a);(/^command timed out after \d+s$/.test(t)||t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("multiple sims are connected:")||t.startsWith("saved sim ")||t.startsWith("no sim connected with id ")||t.startsWith("could not connect to ws://")||t.startsWith("rnx bridge daemon is not running")||t.startsWith("rnx bridge lockfile is fresh")||t.startsWith("rnx bridge exited before becoming ready")||t.startsWith(`${m.commandName} open: requested bridge port`)||t.startsWith("background daemon setup is unavailable")||t.startsWith("rnx bridge did not start within"))&&!process.env.SOOTSIM_VERBOSE&&(process.stderr.write(` ${t}
5
+ import{a as g,b as f}from"./chunks/chunk-T33T5MW2.js";import{a as m}from"./chunks/chunk-5AKKSWL5.js";import"./chunks/chunk-BZTXJUGV.js";function A(a){let t=a instanceof Error?a.message:String(a);(/^command timed out after \d+s$/.test(t)||t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("multiple sims are connected:")||t.startsWith("saved sim ")||t.startsWith("no sim connected with id ")||t.startsWith("could not connect to ws://")||t.startsWith("rnx bridge daemon is not running")||t.startsWith("rnx bridge lockfile is fresh")||t.startsWith("rnx bridge exited before becoming ready")||t.startsWith(`${m.commandName} open: requested bridge port`)||t.startsWith("background daemon setup is unavailable")||t.startsWith("rnx bridge did not start within"))&&!process.env.SOOTSIM_VERBOSE&&(process.stderr.write(` ${t}
6
6
  `),process.exit(1)),a instanceof Error&&a.stack?process.stderr.write(`${a.stack}
7
7
  `):process.stderr.write(`${t}
8
8
  `),process.exit(1)}process.on("unhandledRejection",A);process.on("uncaughtException",A);var k=typeof __SOOTSIM_STANDALONE__<"u"&&__SOOTSIM_STANDALONE__,S=new Set(["desktop"]);function C(a){!k||!S.has(a)||(process.stderr.write(` ${m.commandName} ${a} isn't available in the standalone binary \u2014
9
9
  it needs vite / electron / playwright from a project's node_modules.
10
10
  run the npm package instead:
11
11
  ${m.commandName} ${a}
12
- `),process.exit(1))}var e=f(process.argv);if(!e.command&&e.commandArgs.length>0){let{resolveHiddenRuntimeAlias:a}=await import("./chunks/hidden-runtime-alias-HSGN3GN4.js");e=a(e)}var $=e.command==="cleanup"&&e.commandArgs.length===1&&e.commandArgs[0]==="--automatic-worker",_=!e.command&&e.commandArgs.length===0;if(!$&&!_&&!e.help&&!e.version&&e.command!=="config"&&e.command!=="setup"&&e.command!=="telemetry"){let{ensurePrivacyChoice:a}=await import("./chunks/privacy-SIDMP5EF.js");await a({prompt:!0})}if(e.command!=="serve"&&e.command!=="daemon"){let{consumeRuntimeUpgradeNotice:a}=await import("./chunks/home-paths-BIUN4CBO.js"),t=a();t&&process.stderr.write(` ${m.name} engine upgraded to v${t.to}`+(t.from?` (from v${t.from})`:"")+` \xB7 what's new: ${m.origin}/changelog
13
- `)}var h=!1;async function v(){if(!h&&(h=!0,!(e.command==="cleanup"||e.command==="serve"||e.command==="agent-wrapper"||e.command==="daemon"&&e.commandArgs[0]==="uninstall")))try{let{isAutomaticSootsimCleanupComplete:a}=await import("./chunks/disk-cleanup-5R7JYCO6.js");if(a())return;let{spawn:t}=await import("node:child_process"),i=["cleanup","--automatic-worker"],d=process.argv[1],p=k?t(process.execPath,i,{detached:!0,stdio:["ignore","ignore","inherit"],env:process.env}):d?t(process.execPath,[d,...i],{detached:!0,stdio:["ignore","ignore","inherit"],env:process.env}):t(m.commandName,i,{detached:!0,stdio:["ignore","ignore","inherit"],env:process.env});p.once("error",u=>{process.stderr.write(` ${m.name} automatic cleanup will retry on the next run: ${u.message}
12
+ `),process.exit(1))}var e=f(process.argv);if(!e.command&&e.commandArgs.length>0){let{resolveHiddenRuntimeAlias:a}=await import("./chunks/hidden-runtime-alias-A4TMRHFA.js");e=a(e)}var $=e.command==="cleanup"&&e.commandArgs.length===1&&e.commandArgs[0]==="--automatic-worker",_=!e.command&&e.commandArgs.length===0;if(!$&&!_&&!e.help&&!e.version&&e.command!=="config"&&e.command!=="setup"&&e.command!=="telemetry"){let{ensurePrivacyChoice:a}=await import("./chunks/privacy-AYLEWFZX.js");await a({prompt:!0})}if(e.command!=="serve"&&e.command!=="daemon"){let{consumeRuntimeUpgradeNotice:a}=await import("./chunks/home-paths-A2ANFZHA.js"),t=a();t&&process.stderr.write(` ${m.name} engine upgraded to v${t.to}`+(t.from?` (from v${t.from})`:"")+` \xB7 what's new: ${m.origin}/changelog
13
+ `)}var h=!1;async function v(){if(!h&&(h=!0,!(e.command==="cleanup"||e.command==="serve"||e.command==="agent-wrapper"||e.command==="daemon"&&e.commandArgs[0]==="uninstall")))try{let{isAutomaticSootsimCleanupComplete:a}=await import("./chunks/disk-cleanup-HWA4ATEL.js");if(a())return;let{spawn:t}=await import("node:child_process"),i=["cleanup","--automatic-worker"],d=process.argv[1],p=k?t(process.execPath,i,{detached:!0,stdio:["ignore","ignore","inherit"],env:process.env}):d?t(process.execPath,[d,...i],{detached:!0,stdio:["ignore","ignore","inherit"],env:process.env}):t(m.commandName,i,{detached:!0,stdio:["ignore","ignore","inherit"],env:process.env});p.once("error",u=>{process.stderr.write(` ${m.name} automatic cleanup will retry on the next run: ${u.message}
14
14
  `)}),p.unref()}catch(a){process.stderr.write(` ${m.name} automatic cleanup will retry on the next run: ${a instanceof Error?a.message:String(a)}
15
- `)}}async function o(a){let{flushCliTelemetry:t}=await import("./chunks/telemetry-FANCQHKG.js");await t(),await v(),process.exit(a)}if(e.version){let{getCliVersion:a}=await import("./chunks/cli-version-VSDCFXXN.js"),{IS_BETA:t,BETA_LABEL:i}=await import("./chunks/beta-XVY4WOYH.js"),d=t?` \xB7 ${i}`:"";console.log(`${m.commandName} v${a()}${d}`);let{readActiveRuntime:p}=await import("./chunks/home-paths-BIUN4CBO.js"),u=p();console.log(u?`runtime v${u}`:"runtime not installed"),await o(0)}if(e.help&&!e.command){let{printHelp:a}=await import("./chunks/help-3ZL7MRUX.js");a(),await o(0)}var n=e.globalFlags.port,c=e.verbose,w=e.globalFlags.device,l=e.globalFlags.theme,W=e.globalFlags.driver,x=e.globalFlags.headless===!0,b=e.globalFlags.sim??e.globalFlags.session??e.globalFlags.tab,r=b?["--sim",b,...e.commandArgs]:e.commandArgs;if(w||l){let{settingsStore:a}=await import("./chunks/store-3EQT7VU6.js"),t={};w&&(t.deviceModel=w),l&&(t.colorScheme=l),a.apply(t)}if(!e.command&&e.commandArgs.length===0){let{runWelcome:a}=await import("./chunks/welcome-3CQ2GE4F.js");await o(await a())}var s=e.command??"";if(!s){if(e.commandArgs.length>0){let t=e.commandArgs.find(i=>!i.startsWith("-"))??e.commandArgs[0];console.error(` unknown command: ${t}`),console.error(` run \`${m.commandName} --help\` to see the full surface.`),await o(1)}let{printHelp:a}=await import("./chunks/help-3ZL7MRUX.js");a(),await o(0)}if(e.help||e.commandArgs.includes("--help")||e.commandArgs.includes("-h")){if(s==="skill"){let{runSkill:i}=await import("./chunks/skills-4JGPOSFE.js");await i(e.commandArgs),await o(0)}if(s==="state"){let{runState:i}=await import("./chunks/state-DEAQFKVP.js");await o(await i(r,{port:n}))}if(s==="reset"){let{runReset:i}=await import("./chunks/reset-GPHG5XN3.js");await o(await i(r,{port:n}))}let a=s==="do"||s==="get"||s==="debug"||s==="shell"||s==="perf"||s==="wait",t=e.commandArgs.find(i=>!i.startsWith("-"));if(!(s==="shell"||s==="perf"))if(a&&!t){let{printGroupHelp:i}=await import("./chunks/help-3ZL7MRUX.js");i(s)&&await o(0)}else{let{printCommandHelp:i}=await import("./chunks/help-3ZL7MRUX.js");i(a&&t?t:s,{prefer:a&&t?"verb":"command",group:a&&t?s:void 0}),await o(0)}}C(s);if(g.has(s)){let{runInspect:a}=await import("./chunks/inspect-RCU7XVAO.js");await a([s,...r],{port:n,verbose:c})}else switch(s){case"assert":{let{runAssert:a}=await import("./chunks/assert-3KQYZDDK.js");await a(e.commandArgs);break}case"detox":{let{runDetox:a}=await import("./chunks/detox-KAKTJ4P4.js");await a(e.commandArgs,{port:n,verbose:c});break}case"maestro":{let{runMaestro:a}=await import("./chunks/maestro-SJGV7B3W.js"),t=await a(r,{port:n,verbose:c});await o(typeof t=="number"?t:0)}case"record":{let{runRecord:a}=await import("./chunks/record-MA3AI752.js");await a(r,{port:n,verbose:c});break}case"film":{let{runFilm:a}=await import("./chunks/film-GY5U752Q.js"),t=await a(r,{port:n,verbose:c});await o(typeof t=="number"?t:0)}case"storage":{let{runStorage:a}=await import("./chunks/storage-Y6F5NTGH.js"),t=await a(r,{port:n,verbose:c});await o(typeof t=="number"?t:0)}case"state":{let{runState:a}=await import("./chunks/state-DEAQFKVP.js"),t=await a(r,{port:n});await o(t)}case"reset":{let{runReset:a}=await import("./chunks/reset-GPHG5XN3.js"),t=await a(r,{port:n});await o(t)}case"perf":{let{runPerf:a}=await import("./chunks/perf-XGANSJT3.js"),t=await a(r,{port:n,verbose:c});await o(typeof t=="number"?t:0)}case"screenshot":{let{runScreenshotCommand:a}=await import("./chunks/screenshot-command-JUXMWXS5.js"),t=await a(r,{port:n,verbose:c});await o(typeof t=="number"?t:0)}case"camera":{let{runCamera:a}=await import("./chunks/camera-JROBX5GM.js"),t=await a(r,{port:n});await o(typeof t=="number"?t:0)}case"mode":{let{runMode:a}=await import("./chunks/mode-MN7LZCLB.js");await a(r,{port:n,verbose:c});break}case"permissions":{let{runPermissions:a}=await import("./chunks/permissions-25UWEJKW.js"),t=await a(r,{port:n,verbose:c});await o(t)}case"debug":{let{runDebug:a}=await import("./chunks/debug-3P2DUTUQ.js");await a(r,{port:n,verbose:c});break}case"timeline":{let{runTimeline:a}=await import("./chunks/timeline-HOHYYDOC.js");await a(r,{port:n,verbose:c});break}case"what-happened":{let{runWhatHappened:a}=await import("./chunks/what-happened-L56ZFIMJ.js");await a(r,{port:n,verbose:c});break}case"open":{let{runOpenCommand:a}=await import("./chunks/control-J35HAFZA.js");await a(r,{port:n});break}case"use":{let{runUseCommand:a}=await import("./chunks/control-J35HAFZA.js");await a(r,{port:n});break}case"claim":{let{runClaimCommand:a}=await import("./chunks/control-J35HAFZA.js");await a(r,{port:n});break}case"close":{let{runCloseCommand:a}=await import("./chunks/control-J35HAFZA.js");await a(r,{port:n});break}case"device":{let{runDeviceCommand:a}=await import("./chunks/device-4MAWLZMR.js");await a(r,{port:n});break}case"compat":{let{runCompat:a}=await import("./chunks/compat-C3RGYGXL.js");await a(e.commandArgs);break}case"report-issue":{let{runReportIssue:a}=await import("./chunks/report-issue-4DTESWE2.js"),t=await a(e.commandArgs);await o(t)}case"desktop":{let{runDesktop:a}=await import("./chunks/desktop-XIXW34VW.js");await a(e.commandArgs,{port:n,device:w});break}case"login":{let{runLogin:a}=await import("./chunks/login-WKNMS4GG.js");await a(e.commandArgs);break}case"logout":{let{runLogout:a}=await import("./chunks/logout-6UFUOESK.js");await a();break}case"auth":{let{runAuth:a}=await import("./chunks/auth-RFE3J27C.js");await a(e.commandArgs);break}case"setup":{let{runSetup:a}=await import("./chunks/setup-G2WYLPM6.js");await a(e.commandArgs);break}case"serve":{let{runServe:a}=await import("./chunks/serve-H7GNKJSM.js");await a(e.commandArgs,{port:n});break}case"daemon":{let{runDaemon:a}=await import("./chunks/daemon-DLLEODJY.js");await a(e.commandArgs,{port:n});break}case"runtime":{let{runRuntime:a}=await import("./chunks/runtime-VOEIOODA.js");await a(e.commandArgs);break}case"upgrade":{let{runUpgrade:a}=await import("./chunks/upgrade-QF5YHLSG.js");await a(e.commandArgs);break}case"version":{let{runVersion:a}=await import("./chunks/version-PDCKYJLB.js");await a(e.commandArgs);break}case"agent":{let{runAgentCommand:a}=await import("./chunks/agent-FB7RPXO6.js"),t=await a(e.commandArgs);await o(t)}case"agent-wrapper":{let{runAgentWrapper:a}=await import("./chunks/agent-wrapper-LFU3XEIG.js"),t=await a(e.commandArgs);await o(t)}case"skill":{let{runSkill:a}=await import("./chunks/skills-4JGPOSFE.js");await a(e.commandArgs);break}case"app-fonts":{let{runAppFonts:a}=await import("./chunks/app-fonts-FK6SETRG.js");await a(e.commandArgs);break}case"config":{let{runConfig:a}=await import("./chunks/config-CDY2RB7Q.js");await a(e.commandArgs);break}case"cleanup":{let{runCleanup:a}=await import("./chunks/cleanup-F74ISXJC.js"),t=await a(e.commandArgs);await o(t)}default:console.error(` unknown command: ${s}`),console.error(` run \`${m.commandName} --help\` to see the full surface.`),await o(1)}await v();
15
+ `)}}async function o(a){let{flushCliTelemetry:t}=await import("./chunks/telemetry-ANUHW6KD.js");await t(),await v(),process.exit(a)}if(e.version){let{getCliVersion:a}=await import("./chunks/cli-version-HUIGZMTX.js"),{IS_BETA:t,BETA_LABEL:i}=await import("./chunks/beta-SSB7KYRA.js"),d=t?` \xB7 ${i}`:"";console.log(`${m.commandName} v${a()}${d}`);let{readActiveRuntime:p}=await import("./chunks/home-paths-A2ANFZHA.js"),u=p();console.log(u?`runtime v${u}`:"runtime not installed"),await o(0)}if(e.help&&!e.command){let{printHelp:a}=await import("./chunks/help-DSDQRHN3.js");a(),await o(0)}var n=e.globalFlags.port,c=e.verbose,w=e.globalFlags.device,l=e.globalFlags.theme,W=e.globalFlags.driver,x=e.globalFlags.headless===!0,b=e.globalFlags.sim??e.globalFlags.session??e.globalFlags.tab,r=b?["--sim",b,...e.commandArgs]:e.commandArgs;if(w||l){let{settingsStore:a}=await import("./chunks/store-SZX3GXCL.js"),t={};w&&(t.deviceModel=w),l&&(t.colorScheme=l),a.apply(t)}if(!e.command&&e.commandArgs.length===0){let{runWelcome:a}=await import("./chunks/welcome-UE273JKY.js");await o(await a())}var s=e.command??"";if(!s){if(e.commandArgs.length>0){let t=e.commandArgs.find(i=>!i.startsWith("-"))??e.commandArgs[0];console.error(` unknown command: ${t}`),console.error(` run \`${m.commandName} --help\` to see the full surface.`),await o(1)}let{printHelp:a}=await import("./chunks/help-DSDQRHN3.js");a(),await o(0)}if(e.help||e.commandArgs.includes("--help")||e.commandArgs.includes("-h")){if(s==="skill"){let{runSkill:i}=await import("./chunks/skills-4CBIW5IP.js");await i(e.commandArgs),await o(0)}if(s==="state"){let{runState:i}=await import("./chunks/state-AWM3LRRR.js");await o(await i(r,{port:n}))}if(s==="reset"){let{runReset:i}=await import("./chunks/reset-BMGMOHRM.js");await o(await i(r,{port:n}))}let a=s==="do"||s==="get"||s==="debug"||s==="shell"||s==="perf"||s==="wait",t=e.commandArgs.find(i=>!i.startsWith("-"));if(!(s==="shell"||s==="perf"))if(a&&!t){let{printGroupHelp:i}=await import("./chunks/help-DSDQRHN3.js");i(s)&&await o(0)}else{let{printCommandHelp:i}=await import("./chunks/help-DSDQRHN3.js");i(a&&t?t:s,{prefer:a&&t?"verb":"command",group:a&&t?s:void 0}),await o(0)}}C(s);if(g.has(s)){let{runInspect:a}=await import("./chunks/inspect-NXE6LUT6.js");await a([s,...r],{port:n,verbose:c})}else switch(s){case"assert":{let{runAssert:a}=await import("./chunks/assert-2EYNC3CJ.js");await a(e.commandArgs);break}case"detox":{let{runDetox:a}=await import("./chunks/detox-7JI56JTD.js");await a(e.commandArgs,{port:n,verbose:c});break}case"maestro":{let{runMaestro:a}=await import("./chunks/maestro-AQ342FXT.js"),t=await a(r,{port:n,verbose:c});await o(typeof t=="number"?t:0)}case"record":{let{runRecord:a}=await import("./chunks/record-V4MZ33XI.js");await a(r,{port:n,verbose:c});break}case"film":{let{runFilm:a}=await import("./chunks/film-GLGYFHGZ.js"),t=await a(r,{port:n,verbose:c});await o(typeof t=="number"?t:0)}case"storage":{let{runStorage:a}=await import("./chunks/storage-S2LC3T7Q.js"),t=await a(r,{port:n,verbose:c});await o(typeof t=="number"?t:0)}case"state":{let{runState:a}=await import("./chunks/state-AWM3LRRR.js"),t=await a(r,{port:n});await o(t)}case"reset":{let{runReset:a}=await import("./chunks/reset-BMGMOHRM.js"),t=await a(r,{port:n});await o(t)}case"perf":{let{runPerf:a}=await import("./chunks/perf-PUT7IITA.js"),t=await a(r,{port:n,verbose:c});await o(typeof t=="number"?t:0)}case"screenshot":{let{runScreenshotCommand:a}=await import("./chunks/screenshot-command-PK54GDUY.js"),t=await a(r,{port:n,verbose:c});await o(typeof t=="number"?t:0)}case"camera":{let{runCamera:a}=await import("./chunks/camera-VVTXBQXD.js"),t=await a(r,{port:n});await o(typeof t=="number"?t:0)}case"mode":{let{runMode:a}=await import("./chunks/mode-XICLRQZH.js");await a(r,{port:n,verbose:c});break}case"permissions":{let{runPermissions:a}=await import("./chunks/permissions-AHJWQPCL.js"),t=await a(r,{port:n,verbose:c});await o(t)}case"debug":{let{runDebug:a}=await import("./chunks/debug-DO2G2BA7.js");await a(r,{port:n,verbose:c});break}case"timeline":{let{runTimeline:a}=await import("./chunks/timeline-4AWI6M2T.js");await a(r,{port:n,verbose:c});break}case"what-happened":{let{runWhatHappened:a}=await import("./chunks/what-happened-6AHCKADV.js");await a(r,{port:n,verbose:c});break}case"open":{let{runOpenCommand:a}=await import("./chunks/control-JMDFMAHT.js");await a(r,{port:n});break}case"use":{let{runUseCommand:a}=await import("./chunks/control-JMDFMAHT.js");await a(r,{port:n});break}case"claim":{let{runClaimCommand:a}=await import("./chunks/control-JMDFMAHT.js");await a(r,{port:n});break}case"close":{let{runCloseCommand:a}=await import("./chunks/control-JMDFMAHT.js");await a(r,{port:n});break}case"device":{let{runDeviceCommand:a}=await import("./chunks/device-YTRCB26J.js");await a(r,{port:n});break}case"compat":{let{runCompat:a}=await import("./chunks/compat-ST5BY7FP.js");await a(e.commandArgs);break}case"report-issue":{let{runReportIssue:a}=await import("./chunks/report-issue-QBB54OJ5.js"),t=await a(e.commandArgs);await o(t)}case"desktop":{let{runDesktop:a}=await import("./chunks/desktop-M3UETMNI.js");await a(e.commandArgs,{port:n,device:w});break}case"login":{let{runLogin:a}=await import("./chunks/login-OWD44PHN.js");await a(e.commandArgs);break}case"logout":{let{runLogout:a}=await import("./chunks/logout-WV5QPIUW.js");await a();break}case"auth":{let{runAuth:a}=await import("./chunks/auth-BPTC5SFR.js");await a(e.commandArgs);break}case"setup":{let{runSetup:a}=await import("./chunks/setup-FM3JVRMY.js");await a(e.commandArgs);break}case"serve":{let{runServe:a}=await import("./chunks/serve-YPNVL33J.js");await a(e.commandArgs,{port:n});break}case"daemon":{let{runDaemon:a}=await import("./chunks/daemon-VIL2M7RE.js");await a(e.commandArgs,{port:n});break}case"runtime":{let{runRuntime:a}=await import("./chunks/runtime-SYUM3ASK.js");await a(e.commandArgs);break}case"upgrade":{let{runUpgrade:a}=await import("./chunks/upgrade-WSYVILOP.js");await a(e.commandArgs);break}case"version":{let{runVersion:a}=await import("./chunks/version-XE4ZTCON.js");await a(e.commandArgs);break}case"agent":{let{runAgentCommand:a}=await import("./chunks/agent-RHSVLLYV.js"),t=await a(e.commandArgs);await o(t)}case"agent-wrapper":{let{runAgentWrapper:a}=await import("./chunks/agent-wrapper-76J2FUFC.js"),t=await a(e.commandArgs);await o(t)}case"skill":{let{runSkill:a}=await import("./chunks/skills-4CBIW5IP.js");await a(e.commandArgs);break}case"app-fonts":{let{runAppFonts:a}=await import("./chunks/app-fonts-NXSVJTJO.js");await a(e.commandArgs);break}case"config":{let{runConfig:a}=await import("./chunks/config-Z5NEHXI7.js");await a(e.commandArgs);break}case"cleanup":{let{runCleanup:a}=await import("./chunks/cleanup-E7TDW64X.js"),t=await a(e.commandArgs);await o(t)}default:console.error(` unknown command: ${s}`),console.error(` run \`${m.commandName} --help\` to see the full surface.`),await o(1)}await v();
@@ -1,7 +1,7 @@
1
- /*! rnx v0.1.354 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.356 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import{a as b,b as E,c as A,d as l,e as S,g as x,h as j,j as T,n as I,o as k,p as D,q as g,r as O,s as C}from"./chunk-SLD2EMLZ.js";import"./chunk-MIK6LMG4.js";import{c as $}from"./chunk-CUK6Y2RR.js";import"./chunk-N3CE6AZP.js";import"./chunk-LC77IVGY.js";import"./chunk-HUU7ZUQK.js";import"./chunk-X2DJK3TB.js";import"./chunk-JJOHJNUQ.js";import"./chunk-TJRKLRNP.js";import"./chunk-UVIWE3LD.js";import{j as y}from"./chunk-LETVUC6M.js";import"./chunk-JWXAXCC6.js";import"./chunk-UI2IFVHB.js";import"./chunk-CKKDXTKV.js";import"./chunk-QQNNY43R.js";import w from"node:fs";import d from"node:path";import{spawn as _}from"node:child_process";import F from"node:net";import{WebSocket as R}from"ws";var c=class extends Error{code;constructor(e,t){super(e),this.name="AgentDaemonError",this.code=t}},f=class{ws;port;commandTimeoutMs;ready;closed=!1;nextId=1;pending=new Map;eventListeners=new Set;statusListeners=new Set;disconnectListeners=new Set;constructor(e={}){this.port=e.port??7668,this.commandTimeoutMs=e.commandTimeoutMs??15e3,this.ws=new R(`ws://localhost:${this.port}`),this.ready=new Promise((t,r)=>{let s=()=>{this.ws.off("error",o),t()},o=i=>{this.ws.off("open",s),r(new c(`could not connect to rnx daemon on port ${this.port}: ${i.message}`,"NO_DAEMON"))};this.ws.once("open",s),this.ws.once("error",o)}),this.ws.on("message",t=>this.handleMessage(t)),this.ws.on("close",()=>this.handleClose()),this.ws.on("error",()=>{})}async waitReady(){return this.ready}async listProjects(){return this.send("agent:list-projects")}async upsertProject(e){return this.send("agent:upsert-project",{input:e})}async deleteProject(e){return this.send("agent:delete-project",{projectId:e})}async autoAttachForUrl(e){return this.send("agent:auto-attach-for-url",{input:e})}async listSessions(e){return this.send("agent:list-sessions",{projectId:e})}async startSession(e){return this.send("agent:start-session",{input:e})}async sendPrompt(e,t){return this.send("agent:send-prompt",{sessionId:e,prompt:t})}async sendClaimedPrompt(e,t){return this.send("agent:send-claimed-prompt",{simId:e,prompt:t})}async endSession(e){return this.send("agent:end-session",{sessionId:e})}async getTranscript(e){return this.send("agent:get-transcript",{sessionId:e})}async getPaths(){return this.send("agent:get-paths")}async subscribeEvents(e){return this.send("agent:subscribe-events",{sessionId:e})}async unsubscribeEvents(e){return this.send("agent:unsubscribe-events",{sessionId:e})}onAgentEvent(e){return this.eventListeners.add(e),()=>this.eventListeners.delete(e)}onSessionStatusChange(e){return this.statusListeners.add(e),()=>this.statusListeners.delete(e)}onDisconnect(e){return this.disconnectListeners.add(e),()=>this.disconnectListeners.delete(e)}close(){if(!this.closed){this.closed=!0;try{this.ws.close()}catch{}}}async send(e,t={}){if(await this.ready,this.closed||this.ws.readyState!==R.OPEN)throw new c("daemon connection is closed","NO_DAEMON");let r=this.nextId++;return new Promise((s,o)=>{let i=setTimeout(()=>{this.pending.delete(r),o(new c(`${e} timed out after ${Math.round(this.commandTimeoutMs/1e3)}s`,"TIMEOUT"))},this.commandTimeoutMs);this.pending.set(r,{resolve:s,reject:o,timer:i});try{this.ws.send(JSON.stringify({id:r,type:e,...t}))}catch(a){clearTimeout(i),this.pending.delete(r),o(a instanceof Error?a:new Error(String(a)))}})}handleMessage(e){let t;try{t=JSON.parse(String(e))}catch{return}if(!t||typeof t!="object")return;if(t.type==="agent:event"){for(let s of this.eventListeners)try{s({sessionId:t.sessionId,event:t.event})}catch{}return}if(t.type==="agent:session-status"){for(let s of this.statusListeners)try{s(t.session)}catch{}return}if(typeof t.id!="number")return;let r=this.pending.get(t.id);r&&(this.pending.delete(t.id),clearTimeout(r.timer),t.error?r.reject(new c(t.error,t.code)):r.resolve(t.result))}handleClose(){if(!this.closed){this.closed=!0;for(let[,e]of this.pending)clearTimeout(e.timer),e.reject(new c("daemon disconnected","DISCONNECT"));this.pending.clear();for(let e of this.disconnectListeners)try{e()}catch{}}}};function M(n=7668,e=400){return new Promise(t=>{let r=new F.Socket,s=!1,o=i=>{s||(s=!0,r.destroy(),t(i))};r.setTimeout(e),r.once("connect",()=>o(!0)),r.once("timeout",()=>o(!1)),r.once("error",()=>o(!1)),r.connect(n,"127.0.0.1")})}async function B(n={}){let e=n.port??7668;if(await M(e))return{alreadyRunning:!0};if(y())throw new c(`no rnx bridge on port ${e}. run \`rnx daemon install\` to enable the faster background service, or \`rnx serve\` in another shell.`,"DEV_HOST_REFUSED");let{cmd:t,prefixArgs:r}=C(),s=[...r,"serve","--quiet"];e!==7668&&s.push("--port",String(e));let o=_(t,s,{detached:!0,stdio:"ignore",env:process.env,cwd:process.cwd()});o.unref();let i=Date.now()+(n.startupTimeoutMs??5e3);for(;Date.now()<i;){if(await M(e))return{alreadyRunning:!1,pid:o.pid};await new Promise(a=>setTimeout(a,100))}throw new c(`spawned rnx daemon on port ${e} but it did not come up in time. run \`rnx serve\` manually to diagnose.`,"SPAWN_TIMEOUT")}async function h(n={}){await B({port:n.port,startupTimeoutMs:n.startupTimeoutMs});let e=new f(n);try{await e.waitReady()}catch(t){throw e.close(),t}return e}async function ge(n){let[e,...t]=n;try{switch(e){case void 0:case"--help":case"-h":case"help":return L(),0;case"attach":return await W(t);case"projects":return await J();case"project":return await V(t);case"sessions":return await H(t);case"start":return await G(t);case"prompt":return await q(t);case"watch":return await K(t);case"transcript":return await z(t);case"end":return await Q(t);case"paths":return await Y();default:return process.stderr.write(`unknown agent subcommand: ${e}
4
+ import{a as b,b as E,c as A,d as l,e as S,g as x,h as j,j as T,n as I,o as k,p as D,q as g,r as O,s as C}from"./chunk-5AF3BFLN.js";import"./chunk-E5ALNGXA.js";import{c as $}from"./chunk-7EAA32OO.js";import"./chunk-ZK67ALEG.js";import"./chunk-SZD4NAQR.js";import"./chunk-AA7PHU2M.js";import"./chunk-VSADIZVW.js";import"./chunk-XT6FA7AH.js";import"./chunk-RQZCBNCD.js";import"./chunk-I3G6YW6L.js";import{j as y}from"./chunk-XJ2LMLUP.js";import"./chunk-FWBQKEAA.js";import"./chunk-5AKKSWL5.js";import"./chunk-6CGOQKVQ.js";import"./chunk-BZTXJUGV.js";import w from"node:fs";import d from"node:path";import{spawn as _}from"node:child_process";import F from"node:net";import{WebSocket as R}from"ws";var c=class extends Error{code;constructor(e,t){super(e),this.name="AgentDaemonError",this.code=t}},f=class{ws;port;commandTimeoutMs;ready;closed=!1;nextId=1;pending=new Map;eventListeners=new Set;statusListeners=new Set;disconnectListeners=new Set;constructor(e={}){this.port=e.port??7668,this.commandTimeoutMs=e.commandTimeoutMs??15e3,this.ws=new R(`ws://localhost:${this.port}`),this.ready=new Promise((t,r)=>{let s=()=>{this.ws.off("error",o),t()},o=i=>{this.ws.off("open",s),r(new c(`could not connect to rnx daemon on port ${this.port}: ${i.message}`,"NO_DAEMON"))};this.ws.once("open",s),this.ws.once("error",o)}),this.ws.on("message",t=>this.handleMessage(t)),this.ws.on("close",()=>this.handleClose()),this.ws.on("error",()=>{})}async waitReady(){return this.ready}async listProjects(){return this.send("agent:list-projects")}async upsertProject(e){return this.send("agent:upsert-project",{input:e})}async deleteProject(e){return this.send("agent:delete-project",{projectId:e})}async autoAttachForUrl(e){return this.send("agent:auto-attach-for-url",{input:e})}async listSessions(e){return this.send("agent:list-sessions",{projectId:e})}async startSession(e){return this.send("agent:start-session",{input:e})}async sendPrompt(e,t){return this.send("agent:send-prompt",{sessionId:e,prompt:t})}async sendClaimedPrompt(e,t){return this.send("agent:send-claimed-prompt",{simId:e,prompt:t})}async endSession(e){return this.send("agent:end-session",{sessionId:e})}async getTranscript(e){return this.send("agent:get-transcript",{sessionId:e})}async getPaths(){return this.send("agent:get-paths")}async subscribeEvents(e){return this.send("agent:subscribe-events",{sessionId:e})}async unsubscribeEvents(e){return this.send("agent:unsubscribe-events",{sessionId:e})}onAgentEvent(e){return this.eventListeners.add(e),()=>this.eventListeners.delete(e)}onSessionStatusChange(e){return this.statusListeners.add(e),()=>this.statusListeners.delete(e)}onDisconnect(e){return this.disconnectListeners.add(e),()=>this.disconnectListeners.delete(e)}close(){if(!this.closed){this.closed=!0;try{this.ws.close()}catch{}}}async send(e,t={}){if(await this.ready,this.closed||this.ws.readyState!==R.OPEN)throw new c("daemon connection is closed","NO_DAEMON");let r=this.nextId++;return new Promise((s,o)=>{let i=setTimeout(()=>{this.pending.delete(r),o(new c(`${e} timed out after ${Math.round(this.commandTimeoutMs/1e3)}s`,"TIMEOUT"))},this.commandTimeoutMs);this.pending.set(r,{resolve:s,reject:o,timer:i});try{this.ws.send(JSON.stringify({id:r,type:e,...t}))}catch(a){clearTimeout(i),this.pending.delete(r),o(a instanceof Error?a:new Error(String(a)))}})}handleMessage(e){let t;try{t=JSON.parse(String(e))}catch{return}if(!t||typeof t!="object")return;if(t.type==="agent:event"){for(let s of this.eventListeners)try{s({sessionId:t.sessionId,event:t.event})}catch{}return}if(t.type==="agent:session-status"){for(let s of this.statusListeners)try{s(t.session)}catch{}return}if(typeof t.id!="number")return;let r=this.pending.get(t.id);r&&(this.pending.delete(t.id),clearTimeout(r.timer),t.error?r.reject(new c(t.error,t.code)):r.resolve(t.result))}handleClose(){if(!this.closed){this.closed=!0;for(let[,e]of this.pending)clearTimeout(e.timer),e.reject(new c("daemon disconnected","DISCONNECT"));this.pending.clear();for(let e of this.disconnectListeners)try{e()}catch{}}}};function M(n=7668,e=400){return new Promise(t=>{let r=new F.Socket,s=!1,o=i=>{s||(s=!0,r.destroy(),t(i))};r.setTimeout(e),r.once("connect",()=>o(!0)),r.once("timeout",()=>o(!1)),r.once("error",()=>o(!1)),r.connect(n,"127.0.0.1")})}async function B(n={}){let e=n.port??7668;if(await M(e))return{alreadyRunning:!0};if(y())throw new c(`no rnx bridge on port ${e}. run \`rnx daemon install\` to enable the faster background service, or \`rnx serve\` in another shell.`,"DEV_HOST_REFUSED");let{cmd:t,prefixArgs:r}=C(),s=[...r,"serve","--quiet"];e!==7668&&s.push("--port",String(e));let o=_(t,s,{detached:!0,stdio:"ignore",env:process.env,cwd:process.cwd()});o.unref();let i=Date.now()+(n.startupTimeoutMs??5e3);for(;Date.now()<i;){if(await M(e))return{alreadyRunning:!1,pid:o.pid};await new Promise(a=>setTimeout(a,100))}throw new c(`spawned rnx daemon on port ${e} but it did not come up in time. run \`rnx serve\` manually to diagnose.`,"SPAWN_TIMEOUT")}async function h(n={}){await B({port:n.port,startupTimeoutMs:n.startupTimeoutMs});let e=new f(n);try{await e.waitReady()}catch(t){throw e.close(),t}return e}async function ge(n){let[e,...t]=n;try{switch(e){case void 0:case"--help":case"-h":case"help":return L(),0;case"attach":return await W(t);case"projects":return await J();case"project":return await V(t);case"sessions":return await H(t);case"start":return await G(t);case"prompt":return await q(t);case"watch":return await K(t);case"transcript":return await z(t);case"end":return await Q(t);case"paths":return await Y();default:return process.stderr.write(`unknown agent subcommand: ${e}
5
5
  `),L(),2}}catch(r){if(r instanceof c)return process.stderr.write(`${r.message}
6
6
  `),1;throw r}}async function v(n){let e=await h({clientLabel:"sootsim-agent-cli"});try{return await n(e)}finally{e.close()}}function L(){$("agent")}function P(n,e){let t={},r=[];for(let s=0;s<n.length;s++){let o=n[s],i=e[o];i==="value"?(t[o]=n[s+1]??"",s++):i==="bool"?t[o]=!0:r.push(o)}return{flags:t,positional:r}}function U(n,e="codex"){return n==="codex"||n==="claude"?n:e}async function W(n){let{flags:e,positional:t}=P(n,{"--name":"value","--provider":"value"}),r=t[0];if(!r)return process.stderr.write(`usage: rnx agent attach <dir> [--name X] [--provider codex|claude]
7
7
  `),2;let s=d.resolve(r);if(!w.existsSync(s))return process.stderr.write(`directory does not exist: ${s}
@@ -1,7 +1,7 @@
1
- /*! rnx v0.1.354 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.356 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import{b as M}from"./chunk-MIK6LMG4.js";import"./chunk-QQNNY43R.js";import{execFile as G,spawn as q}from"node:child_process";import{randomUUID as X}from"node:crypto";import{constants as R,createReadStream as Y,createWriteStream as j,existsSync as C,openSync as J}from"node:fs";import V from"node:fs/promises";import z from"node:path";import K from"node:readline";import{promisify as Q}from"node:util";import{spawn as H}from"node:child_process";import L from"node:readline";var b=class extends Error{code;data;constructor(t,r,m){super(t),this.name="CodexRpcError",this.code=r,this.data=m}};function W(d){let t=H(d.bin,["app-server"],{cwd:d.cwd,env:{...process.env,...d.env},stdio:["pipe","pipe","pipe"]}),r=new Map,m=new Map,u=1,f=!1,a=new Promise(s=>{t.on("exit",(o,e)=>{f=!0;let p=new Error(`codex app-server exited (code=${o}, signal=${e??""})`);for(let{reject:y}of r.values())y(p);r.clear(),s({code:o,signal:e})})});L.createInterface({input:t.stdout,crlfDelay:1/0}).on("line",s=>{let o=s.trim();if(!o)return;let e;try{e=JSON.parse(o)}catch{return}if(e.id!=null&&(e.result!==void 0||e.error!==void 0)){let p=typeof e.id=="string"?Number(e.id):e.id,y=p!=null?r.get(p):void 0;if(!y)return;r.delete(p),e.error?y.reject(new b(e.error.message,e.error.code,e.error.data)):y.resolve(e.result);return}if(e.method){let p=m.get(e.method);if(!p)return;for(let y of p)try{y(e.params)}catch(l){console.error(`[codex-client] handler for "${e.method}" threw:`,l instanceof Error?l.stack??l.message:l)}}}),t.stderr.setEncoding("utf8"),t.stderr.on("data",s=>{let o=m.get("__stderr__");if(o)for(let e of o)try{e({text:s})}catch{}});function n(s){if(!f)try{t.stdin.write(JSON.stringify(s)+`
4
+ import{b as M}from"./chunk-E5ALNGXA.js";import"./chunk-BZTXJUGV.js";import{execFile as G,spawn as q}from"node:child_process";import{randomUUID as X}from"node:crypto";import{constants as R,createReadStream as Y,createWriteStream as j,existsSync as C,openSync as J}from"node:fs";import V from"node:fs/promises";import z from"node:path";import K from"node:readline";import{promisify as Q}from"node:util";import{spawn as H}from"node:child_process";import L from"node:readline";var b=class extends Error{code;data;constructor(t,r,m){super(t),this.name="CodexRpcError",this.code=r,this.data=m}};function W(d){let t=H(d.bin,["app-server"],{cwd:d.cwd,env:{...process.env,...d.env},stdio:["pipe","pipe","pipe"]}),r=new Map,m=new Map,u=1,f=!1,a=new Promise(s=>{t.on("exit",(o,e)=>{f=!0;let p=new Error(`codex app-server exited (code=${o}, signal=${e??""})`);for(let{reject:y}of r.values())y(p);r.clear(),s({code:o,signal:e})})});L.createInterface({input:t.stdout,crlfDelay:1/0}).on("line",s=>{let o=s.trim();if(!o)return;let e;try{e=JSON.parse(o)}catch{return}if(e.id!=null&&(e.result!==void 0||e.error!==void 0)){let p=typeof e.id=="string"?Number(e.id):e.id,y=p!=null?r.get(p):void 0;if(!y)return;r.delete(p),e.error?y.reject(new b(e.error.message,e.error.code,e.error.data)):y.resolve(e.result);return}if(e.method){let p=m.get(e.method);if(!p)return;for(let y of p)try{y(e.params)}catch(l){console.error(`[codex-client] handler for "${e.method}" threw:`,l instanceof Error?l.stack??l.message:l)}}}),t.stderr.setEncoding("utf8"),t.stderr.on("data",s=>{let o=m.get("__stderr__");if(o)for(let e of o)try{e({text:s})}catch{}});function n(s){if(!f)try{t.stdin.write(JSON.stringify(s)+`
5
5
  `)}catch{}}return{exited:a,on(s,o){let e=m.get(s);return e||(e=new Set,m.set(s,e)),e.add(o),()=>{e?.delete(o)}},request(s,o){if(f)return Promise.reject(new Error(`codex app-server closed; cannot call ${s}`));let e=u++;return new Promise((p,y)=>{r.set(e,{resolve:l=>p(l),reject:y,method:s}),n({jsonrpc:"2.0",id:e,method:s,params:o})})},notify(s,o){n({jsonrpc:"2.0",method:s,params:o})},async shutdown(s=1500){if(f)return;try{t.stdin.end()}catch{}let o=setTimeout(()=>{if(!f)try{t.kill("SIGTERM")}catch{}},s);try{await a}finally{clearTimeout(o)}},kill(s="SIGTERM"){if(!f)try{t.kill(s)}catch{}}}}var O="never",F="danger-full-access",Z={type:"dangerFullAccess"},D="fast",ee="medium",te=Q(G);async function ne(d,t){let r=t||d;if(r.includes("/")||r.includes("\\"))return C(r)?{ok:!0,path:r}:{ok:!1,message:`agent binary not found at path: ${r}`};try{let{stdout:m}=await te("which",[r],{timeout:1500}),u=m.trim();return u?{ok:!0,path:u}:{ok:!1,message:`${r} not found on PATH`}}catch{return{ok:!1,message:`${r} not found on PATH. install the ${d} CLI and retry, or pass --${d}-bin /path/to/${d} to agent start.`}}}function re(d){let t={"--session-id":"sessionId","--project-id":"projectId","--provider":"provider","--cwd":"cwd","--prompt-in":"promptIn","--events-out":"eventsOut","--transcript":"transcript","--codex-bin":"codexBin","--claude-bin":"claudeBin","--claude-session-uuid":"claudeSessionUuid"},r={};for(let m=0;m<d.length;m++){let u=d[m];if(u==="--fresh-thread"){r.freshThread=!0;continue}let f=t[u];f&&(r[f]=d[m+1],m++)}return r}async function Ie(d){let t=re(d);if(!t.sessionId||!t.projectId||!t.provider||!t.cwd||!t.promptIn||!t.eventsOut)return process.stderr.write(`usage: rnx agent-wrapper --session-id <id> --project-id <id>
6
6
  --provider codex|claude --cwd <path>
7
7
  --prompt-in <fifo> --events-out <fifo>
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.354 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.356 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import{o as p}from"./chunk-IGV4KCCM.js";import"./chunk-77CBLMD4.js";import"./chunk-THFM2CFT.js";import"./chunk-QQNNY43R.js";import{existsSync as h,mkdirSync as d,readFileSync as y,writeFileSync as g}from"node:fs";import{join as m}from"node:path";import{gzipSync as w}from"node:zlib";function f(t,e){let o=t.indexOf(`--${e}`);if(o!==-1&&o+1<t.length)return t[o+1];let r=t.find(i=>i.startsWith(`--${e}=`));return r?r.slice(e.length+3):void 0}async function x(t){let e=f(t,"wire")||"",o=f(t,"out-dir"),r=f(t,"manifest");if((!o||!r)&&(console.error(" usage: rnx app-fonts stage --wire <wire> --out-dir <dir> --manifest <path>"),process.exit(1)),!e.trim()){console.log("no app fonts declared \u2014 nothing to stage");return}d(o,{recursive:!0});let i=await p(e,{onStaged:({url:n,byteLength:s})=>console.log(` staged app font: ${n} (${(s/1024).toFixed(1)} KiB)`),onError:(n,s)=>console.error(` warning: failed to fetch app font ${n}: ${s instanceof Error?s.message:s}`)}),a=[];for(let n of i){let s=w(n.bytes);g(m(o,n.urlhash),s),a.push({url:n.url,urlhash:n.urlhash,contentType:n.contentType,encoding:"gzip",sizeBytes:s.length,rawBytes:n.bytes.byteLength})}let c=[];if(h(r))try{let n=JSON.parse(y(r,"utf8"));Array.isArray(n)&&(c=n)}catch{}let u=new Set(c.map(n=>n.urlhash)),l=[...c,...a.filter(n=>!u.has(n.urlhash))];g(r,JSON.stringify(l)),console.log(`staged ${a.length} app font(s); manifest now has ${l.length} file(s)`)}async function E(t){let e=t[0];if(e==="stage"){await x(t.slice(1));return}console.error(` unknown app-fonts subcommand: ${e??"(none)"}`),console.error(" available: stage"),process.exit(1)}export{E as runAppFonts};
4
+ import{o as p}from"./chunk-G2SHGCDI.js";import"./chunk-NSEPQLZF.js";import"./chunk-5DAVGCVR.js";import"./chunk-BZTXJUGV.js";import{existsSync as h,mkdirSync as d,readFileSync as y,writeFileSync as g}from"node:fs";import{join as m}from"node:path";import{gzipSync as w}from"node:zlib";function f(t,e){let o=t.indexOf(`--${e}`);if(o!==-1&&o+1<t.length)return t[o+1];let r=t.find(i=>i.startsWith(`--${e}=`));return r?r.slice(e.length+3):void 0}async function x(t){let e=f(t,"wire")||"",o=f(t,"out-dir"),r=f(t,"manifest");if((!o||!r)&&(console.error(" usage: rnx app-fonts stage --wire <wire> --out-dir <dir> --manifest <path>"),process.exit(1)),!e.trim()){console.log("no app fonts declared \u2014 nothing to stage");return}d(o,{recursive:!0});let i=await p(e,{onStaged:({url:n,byteLength:s})=>console.log(` staged app font: ${n} (${(s/1024).toFixed(1)} KiB)`),onError:(n,s)=>console.error(` warning: failed to fetch app font ${n}: ${s instanceof Error?s.message:s}`)}),a=[];for(let n of i){let s=w(n.bytes);g(m(o,n.urlhash),s),a.push({url:n.url,urlhash:n.urlhash,contentType:n.contentType,encoding:"gzip",sizeBytes:s.length,rawBytes:n.bytes.byteLength})}let c=[];if(h(r))try{let n=JSON.parse(y(r,"utf8"));Array.isArray(n)&&(c=n)}catch{}let u=new Set(c.map(n=>n.urlhash)),l=[...c,...a.filter(n=>!u.has(n.urlhash))];g(r,JSON.stringify(l)),console.log(`staged ${a.length} app font(s); manifest now has ${l.length} file(s)`)}async function E(t){let e=t[0];if(e==="stage"){await x(t.slice(1));return}console.error(` unknown app-fonts subcommand: ${e??"(none)"}`),console.error(" available: stage"),process.exit(1)}export{E as runAppFonts};
@@ -1,7 +1,7 @@
1
- /*! rnx v0.1.354 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.356 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import"./chunk-QQNNY43R.js";import{spawn as v}from"child_process";var w=new Set(["describe","find","list","network","logs","count","tree","url","a11y","node","layout","keyboard","errors","warnings","requests","animations","animation","state","sample-color"]),S=new Set(["--exists","--empty","--negate","--quiet","--allow-timeout","!"]),q=new Set(["--count","--count-at-least","--count-at-most","--contains","--not-contains","--matches","--not-matches","--equals","--jq","--has-path","--within"]),P=new Set(["--path-equals"]);function j(s){let r=[],u=[],n=0,e=!1,t=!1,i=!1;for(let o=0;o<s.length;o++){let a=s[o];if(a==="--within"){let c=Number(s[o+1]);if(!Number.isFinite(c)||c<0)return{error:`--within requires a non-negative number, got: ${s[o+1]}`};n=c,o++;continue}if(a==="--negate"||a==="!"){e=!0;continue}if(a==="--quiet"){t=!0;continue}if(a==="--allow-timeout"){i=!0;continue}if(S.has(a)){u.push({kind:a,args:[]});continue}if(q.has(a)){let c=s[o+1];if(c==null)return{error:`${a} requires a value`};u.push({kind:a,args:[c]}),o++;continue}if(P.has(a)){let c=s[o+1],f=s[o+2];if(c==null||f==null)return{error:`${a} requires <path> <value>`};u.push({kind:a,args:[c,f]}),o+=2;continue}r.push(a)}return r.length===0?{error:"assert requires a verb (e.g. find, describe, get errors)"}:{verbArgs:r,predicates:u,withinMs:n,negate:e,quiet:t,allowTimeout:i}}function N(s){return s[0]==="get"||s[0]==="debug"?w.has(s[1])?s[1]:null:s[0]==="do"||s[0]==="wait"?null:w.has(s[0])?s[0]:null}async function R(s){let u=[process.argv[1],...s,"--json"];return new Promise(n=>{let e=v(process.execPath,u,{stdio:["ignore","pipe","pipe"],env:process.env}),t="",i="";e.stdout.on("data",o=>t+=o.toString()),e.stderr.on("data",o=>i+=o.toString()),e.on("error",o=>{n({ok:!1,payload:null,reason:`spawn failed: ${o.message}`})}),e.on("close",o=>{if(o!==0){let a=i.trim().split(`
4
+ import"./chunk-BZTXJUGV.js";import{spawn as v}from"child_process";var w=new Set(["describe","find","list","network","logs","count","tree","url","a11y","node","layout","keyboard","errors","warnings","requests","animations","animation","state","sample-color"]),S=new Set(["--exists","--empty","--negate","--quiet","--allow-timeout","!"]),q=new Set(["--count","--count-at-least","--count-at-most","--contains","--not-contains","--matches","--not-matches","--equals","--jq","--has-path","--within"]),P=new Set(["--path-equals"]);function j(s){let r=[],u=[],n=0,e=!1,t=!1,i=!1;for(let o=0;o<s.length;o++){let a=s[o];if(a==="--within"){let c=Number(s[o+1]);if(!Number.isFinite(c)||c<0)return{error:`--within requires a non-negative number, got: ${s[o+1]}`};n=c,o++;continue}if(a==="--negate"||a==="!"){e=!0;continue}if(a==="--quiet"){t=!0;continue}if(a==="--allow-timeout"){i=!0;continue}if(S.has(a)){u.push({kind:a,args:[]});continue}if(q.has(a)){let c=s[o+1];if(c==null)return{error:`${a} requires a value`};u.push({kind:a,args:[c]}),o++;continue}if(P.has(a)){let c=s[o+1],f=s[o+2];if(c==null||f==null)return{error:`${a} requires <path> <value>`};u.push({kind:a,args:[c,f]}),o+=2;continue}r.push(a)}return r.length===0?{error:"assert requires a verb (e.g. find, describe, get errors)"}:{verbArgs:r,predicates:u,withinMs:n,negate:e,quiet:t,allowTimeout:i}}function N(s){return s[0]==="get"||s[0]==="debug"?w.has(s[1])?s[1]:null:s[0]==="do"||s[0]==="wait"?null:w.has(s[0])?s[0]:null}async function R(s){let u=[process.argv[1],...s,"--json"];return new Promise(n=>{let e=v(process.execPath,u,{stdio:["ignore","pipe","pipe"],env:process.env}),t="",i="";e.stdout.on("data",o=>t+=o.toString()),e.stderr.on("data",o=>i+=o.toString()),e.on("error",o=>{n({ok:!1,payload:null,reason:`spawn failed: ${o.message}`})}),e.on("close",o=>{if(o!==0){let a=i.trim().split(`
5
5
  `).slice(-2).join(" | ").slice(0,200);n({ok:!1,payload:null,reason:`verb exited ${o}${a?`: ${a}`:""}`});return}if(!t.trim()){n({ok:!1,payload:null,reason:"verb produced no output"});return}try{let a=JSON.parse(t);n({ok:!0,payload:a})}catch{n({ok:!1,payload:null,reason:`verb output was not valid json: ${t.slice(0,120)}`})}})})}function y(s,r){let u=r.split(".").filter(e=>e.length>0),n=s;for(let e of u){if(n==null)return{found:!1};if(Array.isArray(n)){let t=Number(e);if(!Number.isInteger(t)||t<0||t>=n.length)return{found:!1};n=n[t];continue}if(typeof n=="object"){let t=n;if(!(e in t))return{found:!1};n=t[e];continue}return{found:!1}}return{found:!0,value:n}}function d(s){return Array.isArray(s)?s.length:s&&typeof s=="object"?Object.keys(s).length:null}async function A(s,r){let{kind:u,args:n}=s;switch(u){case"--exists":return r==null?{ok:!1,reason:"payload is null"}:d(r)===0?{ok:!1,reason:"payload is empty"}:{ok:!0,reason:"exists"};case"--empty":{if(r==null)return{ok:!0,reason:"payload is null"};let e=d(r);return e===0?{ok:!0,reason:"payload is empty"}:{ok:!1,reason:`payload has ${e} item(s)`}}case"--count":{let e=Number(n[0]),t=d(r);return t==null?{ok:!1,reason:`payload not countable (${typeof r})`}:{ok:t===e,reason:`count=${t}, want=${e}`}}case"--count-at-least":{let e=Number(n[0]),t=d(r);return t==null?{ok:!1,reason:"payload not countable"}:{ok:t>=e,reason:`count=${t}, want>=${e}`}}case"--count-at-most":{let e=Number(n[0]),t=d(r);return t==null?{ok:!1,reason:"payload not countable"}:{ok:t<=e,reason:`count=${t}, want<=${e}`}}case"--contains":{let e=n[0],t=JSON.stringify(r);return{ok:t.includes(e),reason:t.includes(e)?`contains "${e}"`:`missing "${e}"`}}case"--not-contains":{let e=n[0],t=JSON.stringify(r);return{ok:!t.includes(e),reason:t.includes(e)?`unexpected "${e}"`:`not contains "${e}"`}}case"--matches":{let e=new RegExp(n[0]),t=JSON.stringify(r),i=e.test(t);return{ok:i,reason:i?`matches /${n[0]}/`:`no match for /${n[0]}/`}}case"--not-matches":{let e=new RegExp(n[0]),t=JSON.stringify(r),i=!e.test(t);return{ok:i,reason:i?`not matches /${n[0]}/`:`unexpected /${n[0]}/`}}case"--equals":{let e=n[0],t=typeof r=="string"?r:typeof r=="number"||typeof r=="boolean"?String(r):JSON.stringify(r);return{ok:t===e,reason:`got=${JSON.stringify(t)}, want=${JSON.stringify(e)}`}}case"--has-path":{let e=y(r,n[0]);return{ok:e.found,reason:e.found?`path ${n[0]} present`:`path ${n[0]} missing`}}case"--path-equals":{let[e,t]=n,i=y(r,e);if(!i.found)return{ok:!1,reason:`path ${e} missing`};let o=typeof i.value=="string"||typeof i.value=="number"||typeof i.value=="boolean"?String(i.value):JSON.stringify(i.value);return{ok:o===t,reason:`${e}=${o}, want=${t}`}}case"--jq":{let e=n[0];try{let i=(await O(e,r)).trim();return{ok:i.length>0&&i!=="null"&&i!=="false"&&i!=='""',reason:`jq: ${i.slice(0,120)}`}}catch(t){throw new Error(`jq evaluation failed: ${t.message}`)}}default:return{ok:!1,reason:`unknown predicate ${u}`}}}function O(s,r){return new Promise((u,n)=>{let e=v("jq",[s],{stdio:["pipe","pipe","pipe"]}),t="",i="";e.stdout.on("data",o=>t+=o.toString()),e.stderr.on("data",o=>i+=o.toString()),e.on("error",n),e.on("close",o=>{if(o!==0){n(new Error(i.trim()||`jq exited ${o}`));return}u(t)}),e.stdin.end(JSON.stringify(r))})}async function T(s){(s[0]==="--help"||s[0]==="-h"||s.length===0)&&(J(),process.exit(s.length===0?2:0));let r=j(s);"error"in r&&(process.stderr.write(` assert: ${r.error}
6
6
  `),process.exit(2));let{verbArgs:u,predicates:n,withinMs:e,negate:t,quiet:i,allowTimeout:o}=r;N(u)||(process.stderr.write(` assert: unknown or non-read verb: ${u.join(" ")}
7
7
  supported: ${Array.from(w).sort().join(", ")}
@@ -1,7 +1,7 @@
1
- /*! rnx v0.1.354 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.356 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import{a as r}from"./chunk-ENPWD62S.js";import{d as t}from"./chunk-4AQCDL24.js";import"./chunk-LETVUC6M.js";import"./chunk-QQNNY43R.js";function i(){console.log(`
4
+ import{a as r}from"./chunk-CK4C6GPT.js";import{d as t}from"./chunk-TLA6GLYI.js";import"./chunk-XJ2LMLUP.js";import"./chunk-BZTXJUGV.js";function i(){console.log(`
5
5
  rnx auth \u2014 inspect CLI auth
6
6
 
7
7
  usage:
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.354 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.356 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
- import{a,b,c,d}from"./chunk-CKKDXTKV.js";import"./chunk-QQNNY43R.js";export{d as BETA_ASK_HEADLINE,b as BETA_LABEL,c as BETA_TAGLINE,a as IS_BETA};
4
+ import{a,b,c,d}from"./chunk-6CGOQKVQ.js";import"./chunk-BZTXJUGV.js";export{d as BETA_ASK_HEADLINE,b as BETA_LABEL,c as BETA_TAGLINE,a as IS_BETA};