rnxsim 0.1.458 → 0.1.460
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 +13 -10
- package/cli/commands/inspect/actions.ts +20 -127
- package/cli/commands/inspect/core.ts +4 -19
- package/cli/commands/inspect/keyboard.ts +1 -0
- package/cli/commands/inspect/resolve-target.ts +3 -1
- package/cli/commands/inspect.ts +2 -0
- package/cli/drivers/playwright-sim-host.ts +24 -0
- 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-input.cjs +24 -3
- package/dist-lib/bridge-contract-input.mjs +22 -2
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +12 -7
- 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 +26 -72
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.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 +26 -72
- package/dist-lib/sdk.mjs +26 -72
- package/dist-lib/skills.cjs +756 -133
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/src/bridge-contract-input.ts +22 -2
- package/src/host/bridge-host.ts +14 -8
- package/src/sim-client.ts +14 -2
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.460 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
import { SIM_LONG_PRESS_MAX_MS } from './bridge-contract'
|
|
1
2
|
// untrusted JSON -> bridge-contract argument. one owner for that conversion, so
|
|
2
3
|
// every transport in front of a sim (the RNX Cloud sim service's HTTP and
|
|
3
4
|
// WebSocket routes) validates its request bodies here rather than growing a
|
|
4
5
|
// second reader for the same shapes.
|
|
5
|
-
|
|
6
|
-
import { SIM_LONG_PRESS_MAX_MS } from './bridge-contract'
|
|
7
6
|
import type {
|
|
8
7
|
ResetOptions,
|
|
9
8
|
SemanticWaitOptions,
|
|
@@ -13,6 +12,7 @@ import type {
|
|
|
13
12
|
SimStateOptions,
|
|
14
13
|
} from './bridge-contract'
|
|
15
14
|
import type { SimPerformStep, SimScreenshotOptions } from './sim-client'
|
|
15
|
+
import type { SootSimReplayTarget } from '@rnx/globals'
|
|
16
16
|
|
|
17
17
|
/** the caller sent a value this bridge argument cannot be read from. */
|
|
18
18
|
export class BridgeInputError extends Error {
|
|
@@ -113,6 +113,7 @@ export function parsePerformStep(value: unknown, index: number): SimPerformStep
|
|
|
113
113
|
case 'tap':
|
|
114
114
|
return {
|
|
115
115
|
type,
|
|
116
|
+
target: parseTapTarget(step.target),
|
|
116
117
|
x: numberValue(step.x, `${path}.x`),
|
|
117
118
|
y: numberValue(step.y, `${path}.y`),
|
|
118
119
|
}
|
|
@@ -388,3 +389,22 @@ export function parseScreenshotOptions(value: unknown): SimScreenshotOptions {
|
|
|
388
389
|
}),
|
|
389
390
|
}
|
|
390
391
|
}
|
|
392
|
+
|
|
393
|
+
export function parseTapTarget(value: unknown): SootSimReplayTarget | undefined {
|
|
394
|
+
if (value === undefined) return undefined
|
|
395
|
+
const input = recordValue(value, 'tap.target')
|
|
396
|
+
const target: SootSimReplayTarget = {}
|
|
397
|
+
if (input.nodeId !== undefined && input.nodeId !== null) {
|
|
398
|
+
const nodeId = numberValue(input.nodeId, 'tap.target.nodeId')
|
|
399
|
+
if (!Number.isSafeInteger(nodeId))
|
|
400
|
+
validationFailure('tap.target.nodeId', 'must be an integer')
|
|
401
|
+
target.nodeId = nodeId
|
|
402
|
+
}
|
|
403
|
+
for (const key of ['id', 'testID', 'text', 'type'] as const) {
|
|
404
|
+
if (input[key] !== undefined && input[key] !== null)
|
|
405
|
+
target[key] = stringValue(input[key], `tap.target.${key}`)
|
|
406
|
+
}
|
|
407
|
+
if (target.nodeId === undefined && !target.testID && !target.id)
|
|
408
|
+
validationFailure('tap.target', 'requires nodeId, testID or id')
|
|
409
|
+
return target
|
|
410
|
+
}
|
package/src/host/bridge-host.ts
CHANGED
|
@@ -223,6 +223,7 @@ interface BridgeForwardedCommand {
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
export interface BridgeHostOptions {
|
|
226
|
+
/** use 0 for an OS-assigned port; startAsync returns the bound address. */
|
|
226
227
|
port?: number
|
|
227
228
|
openUrl?: (url: string, options?: OpenUrlOptions) => Promise<void> | void
|
|
228
229
|
/** Contrast-specific excludes for the agent host's dev-server scan. passed
|
|
@@ -466,7 +467,7 @@ export class SootSimBridgeHost {
|
|
|
466
467
|
private static SCAN_FRESH_MS = 2000
|
|
467
468
|
|
|
468
469
|
constructor(opts: BridgeHostOptions = {}) {
|
|
469
|
-
this.preferredPort = opts.port
|
|
470
|
+
this.preferredPort = opts.port ?? DEFAULT_SOOTSIM_BRIDGE_PORT
|
|
470
471
|
this.port = this.preferredPort
|
|
471
472
|
// default off — callers that want the lockfile (rnx serve) opt in.
|
|
472
473
|
this.shouldWriteLockfile = opts.writeLockfile === true
|
|
@@ -537,9 +538,9 @@ export class SootSimBridgeHost {
|
|
|
537
538
|
for (let attempt = 0; attempt < this.portFallbackCount; attempt++) {
|
|
538
539
|
const candidate = this.preferredPort + attempt
|
|
539
540
|
try {
|
|
540
|
-
await this.bindOnce(candidate, options?.silent === true)
|
|
541
|
-
this.effectivePort =
|
|
542
|
-
this.port =
|
|
541
|
+
const boundPort = await this.bindOnce(candidate, options?.silent === true)
|
|
542
|
+
this.effectivePort = boundPort
|
|
543
|
+
this.port = boundPort
|
|
543
544
|
this.startedAt = Date.now()
|
|
544
545
|
if (attempt > 0 && !options?.silent) {
|
|
545
546
|
process.stderr.write(
|
|
@@ -547,7 +548,7 @@ export class SootSimBridgeHost {
|
|
|
547
548
|
)
|
|
548
549
|
}
|
|
549
550
|
this.afterBind()
|
|
550
|
-
return
|
|
551
|
+
return boundPort
|
|
551
552
|
} catch (err: unknown) {
|
|
552
553
|
const e = err as NodeJS.ErrnoException
|
|
553
554
|
if (e?.code !== 'EADDRINUSE') {
|
|
@@ -566,8 +567,8 @@ export class SootSimBridgeHost {
|
|
|
566
567
|
)
|
|
567
568
|
}
|
|
568
569
|
|
|
569
|
-
private bindOnce(port: number, _silent: boolean): Promise<
|
|
570
|
-
return new Promise<
|
|
570
|
+
private bindOnce(port: number, _silent: boolean): Promise<number> {
|
|
571
|
+
return new Promise<number>((resolve, reject) => {
|
|
571
572
|
const server = createServer((req, res) => this.handleHttpRequest(req, res))
|
|
572
573
|
let settled = false
|
|
573
574
|
|
|
@@ -589,6 +590,11 @@ export class SootSimBridgeHost {
|
|
|
589
590
|
// 127.0.0.1 explicitly to avoid the localhost-vs-::1 DNS coinflip.
|
|
590
591
|
server.listen(port, '127.0.0.1', () => {
|
|
591
592
|
if (settled) return
|
|
593
|
+
const address = server.address()
|
|
594
|
+
if (!address || typeof address === 'string') {
|
|
595
|
+
onError(new Error('ws bridge has no bound TCP address'))
|
|
596
|
+
return
|
|
597
|
+
}
|
|
592
598
|
settled = true
|
|
593
599
|
server.removeListener('error', onError)
|
|
594
600
|
server.on('error', (err) => {
|
|
@@ -603,7 +609,7 @@ export class SootSimBridgeHost {
|
|
|
603
609
|
this.wss?.emit('connection', ws, req)
|
|
604
610
|
})
|
|
605
611
|
})
|
|
606
|
-
resolve()
|
|
612
|
+
resolve(address.port)
|
|
607
613
|
})
|
|
608
614
|
})
|
|
609
615
|
}
|
package/src/sim-client.ts
CHANGED
|
@@ -480,11 +480,22 @@ export class SimClient implements WsBridge, InspectBridge {
|
|
|
480
480
|
const { text, ...textOpts } = target
|
|
481
481
|
return this.throwUnlessTapped(await tapByText(this, text, textOpts), text)
|
|
482
482
|
}
|
|
483
|
-
if (
|
|
483
|
+
if (
|
|
484
|
+
'testID' in target &&
|
|
485
|
+
typeof target.testID === 'string' &&
|
|
486
|
+
typeof target.nodeId !== 'number'
|
|
487
|
+
) {
|
|
484
488
|
return this.throwUnlessTapped(await tapById(this, target.testID), target.testID)
|
|
485
489
|
}
|
|
486
490
|
const coords = this.coordsForTapTarget(target)
|
|
487
|
-
const result = await this.send({
|
|
491
|
+
const result = await this.send({
|
|
492
|
+
type: 'tap',
|
|
493
|
+
x: coords.x,
|
|
494
|
+
y: coords.y,
|
|
495
|
+
...('nodeId' in target && typeof target.nodeId === 'number'
|
|
496
|
+
? { target: { nodeId: target.nodeId } }
|
|
497
|
+
: {}),
|
|
498
|
+
})
|
|
488
499
|
if (!isTapSuccess(result)) {
|
|
489
500
|
throw new SimTapError(
|
|
490
501
|
`tap at ${coords.x},${coords.y} missed: ${JSON.stringify(result)}`,
|
|
@@ -559,6 +570,7 @@ export class SimClient implements WsBridge, InspectBridge {
|
|
|
559
570
|
x: target.x,
|
|
560
571
|
y: target.y,
|
|
561
572
|
target: {
|
|
573
|
+
nodeId: target.nodeId,
|
|
562
574
|
testID: target.testID ?? undefined,
|
|
563
575
|
text: target.text ?? undefined,
|
|
564
576
|
type: target.type ?? undefined,
|