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.
- package/cli/bridge-flow-runner.ts +117 -75
- package/cli/commands/inspect/settling.ts +9 -2
- package/cli/commands/maestro.ts +9 -4
- package/cli/outbound-endpoints.ts +1 -1
- package/detox/index.ts +144 -74
- package/detox/proof-frame.cjs +107 -0
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-FB7RPXO6.js → agent-RHSVLLYV.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-LFU3XEIG.js → agent-wrapper-76J2FUFC.js} +2 -2
- package/dist-cli/chunks/{app-fonts-FK6SETRG.js → app-fonts-NXSVJTJO.js} +2 -2
- package/dist-cli/chunks/{assert-3KQYZDDK.js → assert-2EYNC3CJ.js} +2 -2
- package/dist-cli/chunks/{auth-RFE3J27C.js → auth-BPTC5SFR.js} +2 -2
- package/dist-cli/chunks/{beta-XVY4WOYH.js → beta-SSB7KYRA.js} +2 -2
- package/dist-cli/chunks/{camera-JROBX5GM.js → camera-VVTXBQXD.js} +2 -2
- package/dist-cli/chunks/{chunk-YIUIFZAE.js → chunk-2UIMQVMQ.js} +2 -2
- package/dist-cli/chunks/{chunk-B7OMSJXC.js → chunk-3OCUYKVX.js} +2 -2
- package/dist-cli/chunks/{chunk-ZNABCRWX.js → chunk-3QQFGK3A.js} +2 -2
- package/dist-cli/chunks/{chunk-3QLERZYJ.js → chunk-3SYKCLCM.js} +2 -2
- package/dist-cli/chunks/{chunk-BNXXNT3I.js → chunk-4HQXS5PW.js} +2 -2
- package/dist-cli/chunks/{chunk-P4GCLNFM.js → chunk-4V6JMAXO.js} +2 -2
- package/dist-cli/chunks/{chunk-SLD2EMLZ.js → chunk-5AF3BFLN.js} +2 -2
- package/dist-cli/chunks/{chunk-UI2IFVHB.js → chunk-5AKKSWL5.js} +1 -1
- package/dist-cli/chunks/{chunk-THFM2CFT.js → chunk-5DAVGCVR.js} +1 -1
- package/dist-cli/chunks/{chunk-CKKDXTKV.js → chunk-6CGOQKVQ.js} +1 -1
- package/dist-cli/chunks/{chunk-766UIGCS.js → chunk-6TGSJGCM.js} +2 -2
- package/dist-cli/chunks/{chunk-ATQPDEED.js → chunk-6TWYMJCB.js} +2 -2
- package/dist-cli/chunks/{chunk-LRVL5MAX.js → chunk-7E22W7XX.js} +1 -1
- package/dist-cli/chunks/{chunk-CUK6Y2RR.js → chunk-7EAA32OO.js} +2 -2
- package/dist-cli/chunks/{chunk-UX6D4X6B.js → chunk-A2F5B2AB.js} +2 -2
- package/dist-cli/chunks/{chunk-HUU7ZUQK.js → chunk-AA7PHU2M.js} +2 -2
- package/dist-cli/chunks/{chunk-3RW6W3ZO.js → chunk-BMMSSIRU.js} +1 -1
- package/dist-cli/chunks/{chunk-JT4IMNCO.js → chunk-BNZHWG6Z.js} +2 -2
- package/dist-cli/chunks/{chunk-UAYXEP74.js → chunk-BXT37FPN.js} +1 -1
- package/dist-cli/chunks/{chunk-QQNNY43R.js → chunk-BZTXJUGV.js} +1 -1
- package/dist-cli/chunks/{chunk-ENPWD62S.js → chunk-CK4C6GPT.js} +2 -2
- package/dist-cli/chunks/{chunk-ZJUFI3R7.js → chunk-DRHNOXRS.js} +1 -1
- package/dist-cli/chunks/{chunk-MIK6LMG4.js → chunk-E5ALNGXA.js} +1 -1
- package/dist-cli/chunks/{chunk-FPH4TYZO.js → chunk-E7DVCUK4.js} +3 -3
- package/dist-cli/chunks/{chunk-7WANPS3W.js → chunk-EVQNKPUK.js} +2 -2
- package/dist-cli/chunks/{chunk-QRYTCPNO.js → chunk-FAUFZBRY.js} +2 -2
- package/dist-cli/chunks/chunk-FVKAF4VB.js +535 -0
- package/dist-cli/chunks/{chunk-JWXAXCC6.js → chunk-FWBQKEAA.js} +2 -2
- package/dist-cli/chunks/{chunk-IGV4KCCM.js → chunk-G2SHGCDI.js} +2 -2
- package/dist-cli/chunks/{chunk-PHIYWV44.js → chunk-GM6YYN6P.js} +2 -2
- package/dist-cli/chunks/{chunk-UVIWE3LD.js → chunk-I3G6YW6L.js} +1 -1
- package/dist-cli/chunks/{chunk-HIYCRDUP.js → chunk-IUQL37TT.js} +2 -2
- package/dist-cli/chunks/{chunk-LCPZNPIB.js → chunk-JU3ISZ7X.js} +1 -1
- package/dist-cli/chunks/{chunk-4OS3SXPZ.js → chunk-NPH2KUL6.js} +2 -2
- package/dist-cli/chunks/{chunk-77CBLMD4.js → chunk-NSEPQLZF.js} +1 -1
- package/dist-cli/chunks/{chunk-OKFSCCFC.js → chunk-OUMGSDHQ.js} +1 -1
- package/dist-cli/chunks/{chunk-IUL2WUWW.js → chunk-P5F5PM6C.js} +2 -2
- package/dist-cli/chunks/{chunk-GNKXRXND.js → chunk-RBQUFMLX.js} +2 -2
- package/dist-cli/chunks/{chunk-Y4GUWO3X.js → chunk-RFSFQUUJ.js} +1 -1
- package/dist-cli/chunks/{chunk-TJRKLRNP.js → chunk-RQZCBNCD.js} +1 -1
- package/dist-cli/chunks/{chunk-LC77IVGY.js → chunk-SZD4NAQR.js} +2 -2
- package/dist-cli/chunks/{chunk-37S36DFW.js → chunk-T33T5MW2.js} +1 -1
- package/dist-cli/chunks/{chunk-4AQCDL24.js → chunk-TLA6GLYI.js} +2 -2
- package/dist-cli/chunks/{chunk-JT435OOM.js → chunk-TV5LN34R.js} +2 -2
- package/dist-cli/chunks/{chunk-EWPX6LEN.js → chunk-UC6Y77PK.js} +2 -2
- package/dist-cli/chunks/{chunk-IICFLREN.js → chunk-UUD5NLLB.js} +1 -1
- package/dist-cli/chunks/{chunk-GYGDIT5V.js → chunk-VIEN2LIY.js} +2 -2
- package/dist-cli/chunks/{chunk-X2DJK3TB.js → chunk-VSADIZVW.js} +2 -2
- package/dist-cli/chunks/{chunk-JXNR2KAB.js → chunk-VZKPDDYL.js} +2 -2
- package/dist-cli/chunks/{chunk-YXBNGSG6.js → chunk-X2YH3SPS.js} +1 -1
- package/dist-cli/chunks/{chunk-LETVUC6M.js → chunk-XJ2LMLUP.js} +1 -1
- package/dist-cli/chunks/{chunk-24DA3Y2Z.js → chunk-XMNBS5CX.js} +1 -1
- package/dist-cli/chunks/{chunk-JJOHJNUQ.js → chunk-XT6FA7AH.js} +2 -2
- package/dist-cli/chunks/chunk-Z6CATT5W.js +4 -0
- package/dist-cli/chunks/{chunk-N3CE6AZP.js → chunk-ZK67ALEG.js} +2 -2
- package/dist-cli/chunks/{chunk-FEHHM2LV.js → chunk-ZME75NBJ.js} +13 -6
- package/dist-cli/chunks/{cleanup-F74ISXJC.js → cleanup-E7TDW64X.js} +2 -2
- package/dist-cli/chunks/cli-version-HUIGZMTX.js +4 -0
- package/dist-cli/chunks/{compat-C3RGYGXL.js → compat-ST5BY7FP.js} +2 -2
- package/dist-cli/chunks/{config-CDY2RB7Q.js → config-Z5NEHXI7.js} +2 -2
- package/dist-cli/chunks/{control-J35HAFZA.js → control-JMDFMAHT.js} +2 -2
- package/dist-cli/chunks/daemon-VIL2M7RE.js +4 -0
- package/dist-cli/chunks/{debug-3P2DUTUQ.js → debug-DO2G2BA7.js} +3 -3
- package/dist-cli/chunks/{desktop-XIXW34VW.js → desktop-M3UETMNI.js} +3 -3
- package/dist-cli/chunks/{detox-KAKTJ4P4.js → detox-7JI56JTD.js} +2 -2
- package/dist-cli/chunks/{device-4MAWLZMR.js → device-YTRCB26J.js} +2 -2
- package/dist-cli/chunks/{diagnose-A3R7HUYA.js → diagnose-BJT3RXDI.js} +2 -2
- package/dist-cli/chunks/{disk-cleanup-5R7JYCO6.js → disk-cleanup-HWA4ATEL.js} +2 -2
- package/dist-cli/chunks/drivers-HIKMT3EH.js +4 -0
- package/dist-cli/chunks/{film-GY5U752Q.js → film-GLGYFHGZ.js} +3 -3
- package/dist-cli/chunks/flow-AJT2OYLT.js +4 -0
- package/dist-cli/chunks/help-DSDQRHN3.js +4 -0
- package/dist-cli/chunks/{hidden-runtime-alias-HSGN3GN4.js → hidden-runtime-alias-A4TMRHFA.js} +2 -2
- package/dist-cli/chunks/{home-paths-BIUN4CBO.js → home-paths-A2ANFZHA.js} +2 -2
- package/dist-cli/chunks/inspect-NXE6LUT6.js +4 -0
- package/dist-cli/chunks/install-desktop-DMTXQF3R.js +4 -0
- package/dist-cli/chunks/{login-WKNMS4GG.js → login-OWD44PHN.js} +2 -2
- package/dist-cli/chunks/{logout-6UFUOESK.js → logout-WV5QPIUW.js} +2 -2
- package/dist-cli/chunks/{maestro-SJGV7B3W.js → maestro-AQ342FXT.js} +18 -13
- package/dist-cli/chunks/{maestro-generate-PMF2LLKX.js → maestro-generate-AUTBK5QS.js} +3 -3
- package/dist-cli/chunks/{mode-MN7LZCLB.js → mode-XICLRQZH.js} +2 -2
- package/dist-cli/chunks/{optional-demo-registry-HFA27YSP.js → optional-demo-registry-FOXLAYLM.js} +2 -2
- package/dist-cli/chunks/{perf-XGANSJT3.js → perf-PUT7IITA.js} +2 -2
- package/dist-cli/chunks/{permissions-25UWEJKW.js → permissions-AHJWQPCL.js} +2 -2
- package/dist-cli/chunks/privacy-AYLEWFZX.js +4 -0
- package/dist-cli/chunks/{record-MA3AI752.js → record-V4MZ33XI.js} +3 -3
- package/dist-cli/chunks/{report-issue-4DTESWE2.js → report-issue-QBB54OJ5.js} +2 -2
- package/dist-cli/chunks/reset-BMGMOHRM.js +4 -0
- package/dist-cli/chunks/runtime-SYUM3ASK.js +4 -0
- package/dist-cli/chunks/{screenshot-command-JUXMWXS5.js → screenshot-command-PK54GDUY.js} +3 -3
- package/dist-cli/chunks/{screenshot-layers-DJF2E4PE.js → screenshot-layers-AQZK3GRM.js} +2 -2
- package/dist-cli/chunks/{screenshots-capture-UGZU5GOW.js → screenshots-capture-KXQDIF2S.js} +2 -2
- package/dist-cli/chunks/{serve-H7GNKJSM.js → serve-YPNVL33J.js} +2 -2
- package/dist-cli/chunks/setup-FM3JVRMY.js +4 -0
- package/dist-cli/chunks/{skills-4JGPOSFE.js → skills-4CBIW5IP.js} +2 -2
- package/dist-cli/chunks/{state-DEAQFKVP.js → state-AWM3LRRR.js} +2 -2
- package/dist-cli/chunks/{storage-Y6F5NTGH.js → storage-S2LC3T7Q.js} +2 -2
- package/dist-cli/chunks/store-SZX3GXCL.js +4 -0
- package/dist-cli/chunks/telemetry-ANUHW6KD.js +4 -0
- package/dist-cli/chunks/{timeline-HOHYYDOC.js → timeline-4AWI6M2T.js} +2 -2
- package/dist-cli/chunks/{upgrade-QF5YHLSG.js → upgrade-WSYVILOP.js} +2 -2
- package/dist-cli/chunks/upload-U2KPYBGD.js +4 -0
- package/dist-cli/chunks/{version-PDCKYJLB.js → version-XE4ZTCON.js} +2 -2
- package/dist-cli/chunks/{web-C5EUAFFW.js → web-ZS6L2NLF.js} +2 -2
- package/dist-cli/chunks/welcome-UE273JKY.js +5 -0
- package/dist-cli/chunks/{what-happened-L56ZFIMJ.js → what-happened-6AHCKADV.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +196 -54
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +1 -1
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +10 -3
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +10 -3
- package/dist-lib/sdk.mjs +10 -3
- package/dist-lib/skills.cjs +4778 -211
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/skills/rnx-test/SKILL.md +6 -2
- package/src/bridge-contract.ts +8 -2
- package/dist-cli/chunks/chunk-BAWV2UEF.js +0 -543
- package/dist-cli/chunks/chunk-YATZ7U4S.js +0 -4
- package/dist-cli/chunks/cli-version-VSDCFXXN.js +0 -4
- package/dist-cli/chunks/daemon-DLLEODJY.js +0 -4
- package/dist-cli/chunks/drivers-BB3BRKDS.js +0 -4
- package/dist-cli/chunks/flow-ALMSRBVL.js +0 -4
- package/dist-cli/chunks/help-3ZL7MRUX.js +0 -4
- package/dist-cli/chunks/inspect-RCU7XVAO.js +0 -4
- package/dist-cli/chunks/install-desktop-LYVKLTCU.js +0 -4
- package/dist-cli/chunks/privacy-SIDMP5EF.js +0 -4
- package/dist-cli/chunks/reset-GPHG5XN3.js +0 -4
- package/dist-cli/chunks/runtime-VOEIOODA.js +0 -4
- package/dist-cli/chunks/setup-G2WYLPM6.js +0 -4
- package/dist-cli/chunks/store-3EQT7VU6.js +0 -4
- package/dist-cli/chunks/telemetry-FANCQHKG.js +0 -4
- package/dist-cli/chunks/upload-QKJHFAX7.js +0 -4
- 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(
|
|
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
|
|
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
|
|
412
|
-
|
|
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
|
-
:
|
|
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
|
|
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
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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.
|
|
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-
|
|
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.
|
|
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-
|
|
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.
|
|
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-
|
|
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.
|
|
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-
|
|
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.
|
|
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-
|
|
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.
|
|
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-
|
|
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};
|