rnxsim 0.1.376 → 0.1.378
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/README.md +28 -25
- package/cli/app-config.ts +9 -12
- package/cli/app-fonts.ts +3 -3
- package/cli/app-project.ts +8 -8
- package/cli/auth.ts +7 -9
- package/cli/bin.ts +16 -31
- package/cli/bridge-flow-runner.ts +3 -3
- package/cli/browser-backend.ts +44 -0
- package/cli/command-contract.ts +221 -0
- package/cli/command-registry.ts +291 -0
- package/cli/commands/agent-wrapper.ts +2 -2
- package/cli/commands/app-fonts.ts +2 -2
- package/cli/commands/assert.ts +3 -3
- package/cli/commands/auth.ts +1 -1
- package/cli/commands/box/cloud-box.ts +1 -1
- package/cli/commands/box/plane-share.ts +2 -2
- package/cli/commands/box.ts +4 -6
- package/cli/commands/compat.ts +1 -1
- package/cli/commands/config.ts +2 -2
- package/cli/commands/control.ts +29 -29
- package/cli/commands/cpu-profile.ts +7 -7
- package/cli/commands/daemon-mac-app.ts +7 -7
- package/cli/commands/daemon.ts +10 -10
- package/cli/commands/debug.ts +11 -11
- package/cli/commands/detox.ts +13 -13
- package/cli/commands/diagnose.ts +6 -6
- package/cli/commands/do-chain.ts +1 -2
- package/cli/commands/electron.ts +1 -3
- package/cli/commands/film.ts +3 -3
- package/cli/commands/flow.ts +43 -43
- package/cli/commands/inspect/count.ts +1 -1
- package/cli/commands/inspect/describe.ts +1 -1
- package/cli/commands/inspect/env.ts +2 -2
- package/cli/commands/inspect/get-layout.ts +1 -1
- package/cli/commands/inspect/keyboard.ts +1 -1
- package/cli/commands/inspect/list.ts +1 -1
- package/cli/commands/inspect/memory.ts +1 -1
- package/cli/commands/inspect/resolve-target.ts +1 -1
- package/cli/commands/inspect/screens.ts +1 -1
- package/cli/commands/inspect/tree.ts +1 -1
- package/cli/commands/inspect/url.ts +1 -1
- package/cli/commands/inspect/wait-event.ts +5 -5
- package/cli/commands/inspect.ts +34 -34
- package/cli/commands/install-desktop.ts +3 -3
- package/cli/commands/login.ts +6 -6
- package/cli/commands/maestro-generate.ts +5 -5
- package/cli/commands/maestro.ts +5 -5
- package/cli/commands/profile.ts +1 -1
- package/cli/commands/record.ts +9 -9
- package/cli/commands/runtime.ts +18 -18
- package/cli/commands/screenshot-command.ts +1 -1
- package/cli/commands/screenshot-layers.ts +5 -5
- package/cli/commands/screenshot-mode.ts +1 -1
- package/cli/commands/screenshot.ts +8 -8
- package/cli/commands/screenshots-capture.ts +5 -5
- package/cli/commands/serve.ts +3 -3
- package/cli/commands/setup.ts +20 -12
- package/cli/commands/skills.ts +5 -5
- package/cli/commands/slides.ts +1 -1
- package/cli/commands/telemetry.ts +1 -1
- package/cli/commands/three-mode.ts +1 -1
- package/cli/commands/timeline.ts +8 -8
- package/cli/commands/upgrade.ts +116 -131
- package/cli/commands/upload.ts +12 -12
- package/cli/commands/version.ts +7 -7
- package/cli/commands/what-happened.ts +9 -9
- package/cli/current-sim.ts +3 -3
- package/cli/desktop-companion.ts +1 -1
- package/cli/drivers/playwright.ts +9 -9
- package/cli/drivers/registry.ts +1 -1
- package/cli/drivers/types.ts +1 -1
- package/cli/flow-file.ts +2 -2
- package/cli/flow-session.ts +1 -1
- package/cli/help-core.ts +136 -0
- package/cli/help.ts +17 -53
- package/cli/hints.ts +5 -5
- package/cli/inspect-notice-state.ts +1 -1
- package/cli/maestro-js.ts +1 -1
- package/cli/outbound-endpoints.ts +23 -5
- package/cli/parse-args.ts +19 -66
- package/cli/recording-access.ts +1 -1
- package/cli/registry.ts +1 -0
- package/cli/run-registry.ts +1 -1
- package/cli/run-rnx-core.ts +148 -0
- package/cli/run-rnx.ts +6 -9
- package/cli/runtime-notes.ts +3 -3
- package/cli/standalone.ts +4 -0
- package/cli/ws-bridge.ts +8 -8
- package/detox/config-loader.ts +2 -2
- package/detox/index.ts +8 -8
- package/detox/jest-preset.cjs +1 -1
- package/detox/navigation.ts +2 -2
- package/dist-lib/agent-daemon-client.cjs +5 -5
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +2 -2
- package/dist-lib/agent-sessions.cjs +10 -10
- package/dist-lib/attached-projects.cjs +6 -6
- package/dist-lib/auth/shared-session.cjs +6 -6
- 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 +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +25 -25
- package/dist-lib/detox/index.cjs +73 -31
- package/dist-lib/detox/jest-preset.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +29 -29
- package/dist-lib/host/bridge-host.cjs +128 -49
- 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 +14 -14
- 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 +8 -8
- package/dist-lib/profiles.cjs +12 -12
- 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 +8 -8
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +329 -160
- package/dist-lib/vite.cjs +9 -9
- package/package.json +4 -11
- package/scripts/dev-server-scanner.ts +2 -2
- package/scripts/optional-demo-registry.ts +1 -1
- package/skills/contrast/SKILL.md +3 -3
- package/skills/rnx-debug/SKILL.md +1 -1
- package/skills/rnx-test/SKILL.md +2 -2
- package/src/agent-identity.ts +1 -1
- package/src/agent-sessions.ts +7 -5
- package/src/cli-version.ts +12 -4
- package/src/config.ts +26 -28
- package/src/disk-cleanup.ts +11 -11
- package/src/home-paths.ts +28 -28
- package/src/host/bridge-host.ts +16 -16
- package/src/metro-plugin.ts +2 -2
- package/src/profiles.ts +2 -2
- package/src/runtime-assets.ts +7 -7
- package/src/runtime-delivery.ts +13 -13
- package/src/screenshots/orchestrate.ts +1 -1
- package/src/screenshots/schema.ts +2 -2
- package/src/skills/builtin/a11y-review.ts +2 -2
- package/src/skills/builtin/compat-check.ts +2 -2
- package/src/skills/builtin/maestro-test.ts +2 -2
- package/src/skills/builtin/perf-profile.ts +2 -2
- package/src/skills/builtin/screenshot-all.ts +2 -2
- package/src/skills/builtin/visual-diff.ts +2 -2
- package/src/skills/registry.ts +8 -8
- package/src/skills/types.ts +1 -1
- package/src/vite-plugin-one.ts +3 -3
- package/src/vite-plugin.ts +15 -2
- package/dist-cli/bin.js +0 -15
- package/dist-cli/chunks/agent-H42FCKFF.js +0 -48
- package/dist-cli/chunks/agent-wrapper-BBZKTZS6.js +0 -17
- package/dist-cli/chunks/app-fonts-43VXIKF4.js +0 -4
- package/dist-cli/chunks/assert-IXOLVO5Z.js +0 -49
- package/dist-cli/chunks/auth-KFMFB6FU.js +0 -12
- package/dist-cli/chunks/beta-5AO3SJB7.js +0 -4
- package/dist-cli/chunks/box-ZHM66L6K.js +0 -1730
- package/dist-cli/chunks/camera-FNJVFCDQ.js +0 -33
- package/dist-cli/chunks/chunk-37MCSPTE.js +0 -71
- package/dist-cli/chunks/chunk-3PEMSUAQ.js +0 -30
- package/dist-cli/chunks/chunk-4TQ5HOK3.js +0 -7
- package/dist-cli/chunks/chunk-5YZYDEMI.js +0 -4
- package/dist-cli/chunks/chunk-6CV3R3XD.js +0 -15
- package/dist-cli/chunks/chunk-7LGK5XU6.js +0 -4
- package/dist-cli/chunks/chunk-7R2TK2NY.js +0 -4
- package/dist-cli/chunks/chunk-7VZZQQEE.js +0 -497
- package/dist-cli/chunks/chunk-AFOVILIL.js +0 -130
- package/dist-cli/chunks/chunk-BEU7CD7E.js +0 -9
- package/dist-cli/chunks/chunk-CE4JQJ6Y.js +0 -6
- package/dist-cli/chunks/chunk-CIE6CZXL.js +0 -142
- package/dist-cli/chunks/chunk-CSJ7L7ZL.js +0 -312
- package/dist-cli/chunks/chunk-CWCQP53A.js +0 -27
- package/dist-cli/chunks/chunk-DCS5FK5N.js +0 -7
- package/dist-cli/chunks/chunk-DEV3E3MV.js +0 -4
- package/dist-cli/chunks/chunk-DGJMIVZM.js +0 -5
- package/dist-cli/chunks/chunk-DGX3MN65.js +0 -5
- package/dist-cli/chunks/chunk-DNPQMTW5.js +0 -4
- package/dist-cli/chunks/chunk-DOVBJBVD.js +0 -5
- package/dist-cli/chunks/chunk-DPBJ3S3J.js +0 -3
- package/dist-cli/chunks/chunk-FVZBGPCU.js +0 -4
- package/dist-cli/chunks/chunk-GDKMOIUT.js +0 -4
- package/dist-cli/chunks/chunk-GIF2NJCS.js +0 -32
- package/dist-cli/chunks/chunk-GZE57ORL.js +0 -4
- package/dist-cli/chunks/chunk-H3U56DKI.js +0 -24
- package/dist-cli/chunks/chunk-HZLOYAPH.js +0 -4
- package/dist-cli/chunks/chunk-J2IKAEU2.js +0 -4
- package/dist-cli/chunks/chunk-JXAXYK7W.js +0 -11
- package/dist-cli/chunks/chunk-KJE2O2GK.js +0 -4
- package/dist-cli/chunks/chunk-KMNVDZZI.js +0 -423
- package/dist-cli/chunks/chunk-LC3QRIRB.js +0 -10
- package/dist-cli/chunks/chunk-LGFTAQYC.js +0 -4
- package/dist-cli/chunks/chunk-LQMUA5IY.js +0 -4
- package/dist-cli/chunks/chunk-MFIQTWC5.js +0 -4
- package/dist-cli/chunks/chunk-MGALNF2F.js +0 -7
- package/dist-cli/chunks/chunk-MLBZZHOY.js +0 -4
- package/dist-cli/chunks/chunk-NNRF7GIB.js +0 -107
- package/dist-cli/chunks/chunk-NORLYTTO.js +0 -7
- package/dist-cli/chunks/chunk-P6KVGV3H.js +0 -14
- package/dist-cli/chunks/chunk-PAJTUK33.js +0 -4
- package/dist-cli/chunks/chunk-QELIC5XP.js +0 -4
- package/dist-cli/chunks/chunk-QRDF33WD.js +0 -11
- package/dist-cli/chunks/chunk-R76BA7C7.js +0 -535
- package/dist-cli/chunks/chunk-RVEB4CZ2.js +0 -4
- package/dist-cli/chunks/chunk-SK4M7NXT.js +0 -5
- package/dist-cli/chunks/chunk-SKMG5DD7.js +0 -5
- package/dist-cli/chunks/chunk-TEESPOYR.js +0 -4
- package/dist-cli/chunks/chunk-TH2UFGVP.js +0 -4
- package/dist-cli/chunks/chunk-TLP3T3VO.js +0 -4
- package/dist-cli/chunks/chunk-TZUABDIJ.js +0 -38
- package/dist-cli/chunks/chunk-UB2W6OQM.js +0 -99
- package/dist-cli/chunks/chunk-UYVXALPB.js +0 -506
- package/dist-cli/chunks/chunk-VQDYFFIG.js +0 -5
- package/dist-cli/chunks/chunk-VWCNJPCJ.js +0 -5
- package/dist-cli/chunks/chunk-VZIK4WIS.js +0 -74
- package/dist-cli/chunks/chunk-W3FNXAQP.js +0 -4
- package/dist-cli/chunks/chunk-XCDNVNP3.js +0 -4
- package/dist-cli/chunks/chunk-XSVILA4Z.js +0 -4
- package/dist-cli/chunks/chunk-XUTJ7ZWD.js +0 -4
- package/dist-cli/chunks/chunk-YTXY3MHW.js +0 -4
- package/dist-cli/chunks/chunk-ZF7PVX44.js +0 -28
- package/dist-cli/chunks/chunk-ZSSG7OR7.js +0 -4
- package/dist-cli/chunks/cleanup-MLOK2OZA.js +0 -25
- package/dist-cli/chunks/cli-version-OBNR366V.js +0 -4
- package/dist-cli/chunks/compat-SHMFSKU7.js +0 -23
- package/dist-cli/chunks/config-TPEAEUJ2.js +0 -13
- package/dist-cli/chunks/connect-3LEXWTE5.js +0 -4
- package/dist-cli/chunks/control-Z3FWA6BO.js +0 -4
- package/dist-cli/chunks/daemon-RSVYSC65.js +0 -4
- package/dist-cli/chunks/debug-GUVAK2KR.js +0 -200
- package/dist-cli/chunks/desktop-OOP2PTKP.js +0 -31
- package/dist-cli/chunks/detox-C2ILVBEC.js +0 -52
- package/dist-cli/chunks/device-NXIQQJWR.js +0 -18
- package/dist-cli/chunks/diagnose-2JBGYE5L.js +0 -43
- package/dist-cli/chunks/disk-cleanup-VURWJYQV.js +0 -4
- package/dist-cli/chunks/do-chain-DJ4UQC7A.js +0 -5
- package/dist-cli/chunks/drivers-JMA2OIKU.js +0 -4
- package/dist-cli/chunks/env-KTNPKEZR.js +0 -4
- package/dist-cli/chunks/film-DCPS7EID.js +0 -74
- package/dist-cli/chunks/flow-4DZ7B2OA.js +0 -4
- package/dist-cli/chunks/help-34CJMQY2.js +0 -4
- package/dist-cli/chunks/hidden-runtime-alias-HHT2C7WE.js +0 -4
- package/dist-cli/chunks/home-paths-KTPGCPMS.js +0 -4
- package/dist-cli/chunks/inspect-JF5WYJRD.js +0 -4
- package/dist-cli/chunks/install-desktop-ZIC4CDXI.js +0 -4
- package/dist-cli/chunks/login-TTJAOI2Q.js +0 -26
- package/dist-cli/chunks/logout-ERAQ6SKW.js +0 -4
- package/dist-cli/chunks/maestro-W46QCF77.js +0 -108
- package/dist-cli/chunks/maestro-generate-VBLM3MTU.js +0 -36
- package/dist-cli/chunks/mode-ZEDZK7R7.js +0 -26
- package/dist-cli/chunks/optional-demo-registry-ZUTPSVYQ.js +0 -4
- package/dist-cli/chunks/perf-YVT2WXT4.js +0 -48
- package/dist-cli/chunks/permissions-L7VVDHFP.js +0 -13
- package/dist-cli/chunks/platform-7TJOU2FB.js +0 -6
- package/dist-cli/chunks/privacy-57UOTB5J.js +0 -4
- package/dist-cli/chunks/record-VXG37P7U.js +0 -72
- package/dist-cli/chunks/report-issue-WNNOBZHC.js +0 -29
- package/dist-cli/chunks/reset-H5NBFE5U.js +0 -4
- package/dist-cli/chunks/resolve-target-57TK5WLE.js +0 -4
- package/dist-cli/chunks/runtime-QU2NIF2K.js +0 -4
- package/dist-cli/chunks/screenshot-command-AN56TTG7.js +0 -159
- package/dist-cli/chunks/screenshot-layers-3W5R7DB2.js +0 -20
- package/dist-cli/chunks/screenshots-capture-6AWJY7XZ.js +0 -42
- package/dist-cli/chunks/serve-GLYO5Q7J.js +0 -56
- package/dist-cli/chunks/setup-UA2HLD7S.js +0 -4
- package/dist-cli/chunks/sim-client-5C2RDQQO.js +0 -4
- package/dist-cli/chunks/skills-EYXWBRNQ.js +0 -50
- package/dist-cli/chunks/state-REJ7W6K3.js +0 -14
- package/dist-cli/chunks/storage-CFMDHI3V.js +0 -37
- package/dist-cli/chunks/store-XMCUA45G.js +0 -4
- package/dist-cli/chunks/telemetry-FBL3NAKB.js +0 -4
- package/dist-cli/chunks/timeline-HMCHN5FO.js +0 -24
- package/dist-cli/chunks/upgrade-2QSPAA3P.js +0 -7
- package/dist-cli/chunks/upload-DUQBKZYV.js +0 -4
- package/dist-cli/chunks/version-IOA6QFGB.js +0 -6
- package/dist-cli/chunks/web-NCGUYVCJ.js +0 -4
- package/dist-cli/chunks/welcome-QYGSQCWQ.js +0 -5
- package/dist-cli/chunks/what-happened-YTOUK4LO.js +0 -25
- package/dist-cli/chunks/ws-bridge-OF4OZARG.js +0 -4
- package/scripts/postinstall.cjs +0 -3
- package/scripts/preuninstall.cjs +0 -118
package/cli/commands/flow.ts
CHANGED
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
} from './control'
|
|
35
35
|
import { printShellPerfReport } from './inspect'
|
|
36
36
|
import { resolveDefaultUploadOrigin } from './upload'
|
|
37
|
-
import type {
|
|
37
|
+
import type { RNXConfig } from '../../src/config'
|
|
38
38
|
import type { UploadResult } from './upload'
|
|
39
39
|
|
|
40
40
|
export { parseFlowFile, validateFlowFile } from '../flow-file'
|
|
@@ -59,7 +59,7 @@ export function getLastFlowTraceSteps(): SootSimFlowTraceStep[] {
|
|
|
59
59
|
// port and runtime config into the open command.
|
|
60
60
|
export async function resolveAppFrontmatterTarget(
|
|
61
61
|
raw: string,
|
|
62
|
-
): Promise<{ target: string; runtimeConfig?:
|
|
62
|
+
): Promise<{ target: string; runtimeConfig?: RNXConfig }> {
|
|
63
63
|
if (!raw) return { target: '' }
|
|
64
64
|
const trimmed = raw.trim()
|
|
65
65
|
if (!trimmed) return { target: '' }
|
|
@@ -98,19 +98,19 @@ export async function runFlowPlayback(args: string[]): Promise<number> {
|
|
|
98
98
|
lastFlowTraceSteps = []
|
|
99
99
|
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
|
100
100
|
console.log(`
|
|
101
|
-
|
|
101
|
+
rnx maestro — author and run Maestro YAML flows
|
|
102
102
|
|
|
103
103
|
usage:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
rnx maestro test <flow.yaml> [options]
|
|
105
|
+
rnx maestro start
|
|
106
|
+
rnx maestro keep
|
|
107
|
+
rnx maestro end [--output <path>] [--validate] [--video]
|
|
108
|
+
rnx maestro validate <path>
|
|
109
109
|
|
|
110
110
|
options:
|
|
111
111
|
--record record a webm artifact while the flow runs
|
|
112
112
|
--profile capture perf stats while the flow runs
|
|
113
|
-
--out <dir> output directory (default: /tmp/
|
|
113
|
+
--out <dir> output directory (default: /tmp/rnx-recordings)
|
|
114
114
|
--device <model> override the flow frontmatter device for this run
|
|
115
115
|
--slow <ms> delay between steps for natural pacing
|
|
116
116
|
--tail-wait <ms> hold the recording open after the last step so the
|
|
@@ -161,15 +161,15 @@ default runtime:
|
|
|
161
161
|
recording and profiling both run on the same bridge-backed path
|
|
162
162
|
|
|
163
163
|
examples:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
164
|
+
rnx maestro test login.yaml
|
|
165
|
+
rnx maestro test demo.yaml --url 8081 --record --slow 500 --out ./recordings
|
|
166
|
+
rnx maestro test demo.yaml --sim a2
|
|
167
|
+
rnx maestro start
|
|
168
|
+
rnx maestro keep
|
|
169
|
+
rnx maestro end --output ./.maestro/draft.yaml
|
|
170
|
+
rnx maestro end --output ./.maestro/draft.yaml --validate
|
|
171
|
+
rnx maestro end --output ./.maestro/draft.yaml --video
|
|
172
|
+
rnx maestro validate ./.maestro/draft.yaml
|
|
173
173
|
|
|
174
174
|
flow extension:
|
|
175
175
|
takeScreenshot: hero
|
|
@@ -192,14 +192,14 @@ flow extension:
|
|
|
192
192
|
// --headless (you asked to watch it run).
|
|
193
193
|
const headed = args.includes('--headed')
|
|
194
194
|
const openInNewSim = args.includes('--new') || headed
|
|
195
|
-
const outDir = getFlag('--out') || '/tmp/
|
|
195
|
+
const outDir = getFlag('--out') || '/tmp/rnx-recordings'
|
|
196
196
|
// when --screenshots isn't explicitly set, default to the --out directory.
|
|
197
197
|
// this matches what most users expect: one flag controls the whole output
|
|
198
198
|
// bundle (recording + screenshots) for a demo run.
|
|
199
|
-
// previously, screenshots silently landed in /tmp/
|
|
199
|
+
// previously, screenshots silently landed in /tmp/rnx-flow even when
|
|
200
200
|
// --out was set, requiring a second --screenshots flag to redirect them.
|
|
201
201
|
const screenshotDir =
|
|
202
|
-
getFlag('--screenshots') || (getFlag('--out') ? outDir : '/tmp/
|
|
202
|
+
getFlag('--screenshots') || (getFlag('--out') ? outDir : '/tmp/rnx-flow')
|
|
203
203
|
const screenshotPathMode =
|
|
204
204
|
getFlag('--screenshot-paths') === 'flow' ? 'flow' : ('dir' as const)
|
|
205
205
|
// --no-shell makes every takeScreenshot in the flow capture tenant-only
|
|
@@ -330,7 +330,7 @@ flow extension:
|
|
|
330
330
|
const mode = wantElectron ? 'desktop companion' : 'bridge'
|
|
331
331
|
const appLabel = targetApp ? ` | target: ${targetApp}` : ''
|
|
332
332
|
console.log(`
|
|
333
|
-
|
|
333
|
+
rnx maestro — ${path.basename(flowPath)}
|
|
334
334
|
${steps.length} steps | ${mode}${appLabel}${record ? ' | recording' : ''}${profile ? ' | profiling' : ''}${slow ? ` | ${slow}ms delay` : ''}
|
|
335
335
|
`)
|
|
336
336
|
|
|
@@ -427,7 +427,7 @@ flow extension:
|
|
|
427
427
|
: readCurrentSimId() || resolvedBridgeArgs.simId
|
|
428
428
|
// carry the source through so the target-sim notice reads `via --sim`
|
|
429
429
|
// (not the misleading `primary fallback — no sim pinned`) when the flow
|
|
430
|
-
// was actually pinned with --sim or a `
|
|
430
|
+
// was actually pinned with --sim or a `rnx use` selection.
|
|
431
431
|
const pinnedSimIdSource: typeof resolvedBridgeArgs.simIdSource =
|
|
432
432
|
resolvedBridgeArgs.simIdSource === 'flag' ? 'flag' : pinnedSimId ? 'saved' : 'none'
|
|
433
433
|
const bridge = createBridge(resolvedBridgeArgs.wsPort, {
|
|
@@ -437,10 +437,10 @@ flow extension:
|
|
|
437
437
|
})
|
|
438
438
|
let driver: SootSimBridgeFlowRunner
|
|
439
439
|
const applyFlowFrontmatter = async () => {
|
|
440
|
-
const statusBarTime = frontmatter.env?.
|
|
440
|
+
const statusBarTime = frontmatter.env?.RNX_STATUS_BAR_TIME
|
|
441
441
|
if (statusBarTime) {
|
|
442
442
|
if (!/^(?:[1-9]|1[0-2]):[0-5][0-9]$/.test(statusBarTime)) {
|
|
443
|
-
throw new Error('
|
|
443
|
+
throw new Error('RNX_STATUS_BAR_TIME must be a 12-hour time such as 9:41')
|
|
444
444
|
}
|
|
445
445
|
await bridge.send({
|
|
446
446
|
type: 'evaluate',
|
|
@@ -480,7 +480,7 @@ flow extension:
|
|
|
480
480
|
billingOriginOverride: preview ? previewOrigin : undefined,
|
|
481
481
|
// any recording reached via a github installation token is a ci /
|
|
482
482
|
// pr-preview run, so allow it for preview uploads. local flow recording
|
|
483
|
-
// writes a file and matches `
|
|
483
|
+
// writes a file and matches `rnx record --mode video`.
|
|
484
484
|
allowGitHubRecording: preview,
|
|
485
485
|
requireRecordingEntitlement: preview,
|
|
486
486
|
// re-arm the event recorder after every launchApp-with-reload. the
|
|
@@ -550,8 +550,8 @@ flow extension:
|
|
|
550
550
|
// here is redundant and triggers a sim-id rotation on the reload that
|
|
551
551
|
// routes the flow to a stale sim, hanging step 1 ("made no progress …
|
|
552
552
|
// bridge or bundle probably hung"). one reset is enough — the bot
|
|
553
|
-
// signals it did one via
|
|
554
|
-
if (preview && !startsWithLaunchApp && !process.env.
|
|
553
|
+
// signals it did one via RNX_PREVIEW_RESET_DONE.
|
|
554
|
+
if (preview && !startsWithLaunchApp && !process.env.RNX_PREVIEW_RESET_DONE) {
|
|
555
555
|
await driver.launchApp({ clearState: true })
|
|
556
556
|
}
|
|
557
557
|
if (record) {
|
|
@@ -701,9 +701,9 @@ flow extension:
|
|
|
701
701
|
)
|
|
702
702
|
}
|
|
703
703
|
await printBridgeFailureDiagnostics(bridge, {
|
|
704
|
-
errorsCommand: `
|
|
705
|
-
warningsCommand: `
|
|
706
|
-
requestsCommand: `
|
|
704
|
+
errorsCommand: `rnx get errors 5${driver.simId ? ` --sim ${driver.simId}` : ''}`,
|
|
705
|
+
warningsCommand: `rnx get warnings 5${driver.simId ? ` --sim ${driver.simId}` : ''}`,
|
|
706
|
+
requestsCommand: `rnx get requests 5${driver.simId ? ` --sim ${driver.simId}` : ''}`,
|
|
707
707
|
})
|
|
708
708
|
exitCode = 1
|
|
709
709
|
}
|
|
@@ -795,7 +795,7 @@ flow extension:
|
|
|
795
795
|
} else if (driver.simId && driver.simId !== pinnedSimId) {
|
|
796
796
|
// `launchApp clearState` rotates the sim id mid-flow (the shell reconnects
|
|
797
797
|
// under a fresh id). the runner tracks that in-memory, but a directory run
|
|
798
|
-
// (`
|
|
798
|
+
// (`rnx maestro test <dir>`) spawns the next flow fresh — it re-reads
|
|
799
799
|
// the saved sim id, which would still point at the pre-rotation sim and
|
|
800
800
|
// fail with "sim not responding / stale orphan". persist the rotated id so
|
|
801
801
|
// the next flow reuses the live sim. only when we're NOT closing it.
|
|
@@ -847,7 +847,7 @@ async function prepareEventsFile(events: Array<Record<string, any>>): Promise<st
|
|
|
847
847
|
const lines =
|
|
848
848
|
events.map((e) => JSON.stringify(e)).join('\n') + (events.length ? '\n' : '')
|
|
849
849
|
const gz = gzipSync(Buffer.from(lines, 'utf8'))
|
|
850
|
-
const outPath = path.join(tmpdir(), `
|
|
850
|
+
const outPath = path.join(tmpdir(), `rnx-events-${Date.now()}.jsonl.gz`)
|
|
851
851
|
fs.writeFileSync(outPath, gz)
|
|
852
852
|
console.log(` events: ${events.length} written to ${outPath} (${gz.length} bytes gz)`)
|
|
853
853
|
return outPath
|
|
@@ -878,7 +878,7 @@ async function prepareFlowStepTimelineFile(
|
|
|
878
878
|
}))
|
|
879
879
|
const lines = events.map((event) => JSON.stringify(event)).join('\n') + '\n'
|
|
880
880
|
const gz = gzipSync(Buffer.from(lines, 'utf8'))
|
|
881
|
-
const outPath = path.join(tmpdir(), `
|
|
881
|
+
const outPath = path.join(tmpdir(), `rnx-flow-steps-${Date.now()}.jsonl.gz`)
|
|
882
882
|
fs.writeFileSync(outPath, gz)
|
|
883
883
|
console.log(
|
|
884
884
|
` flow trace: ${events.length} step events written to ${outPath} (${gz.length} bytes gz)`,
|
|
@@ -905,14 +905,14 @@ async function prepareFlowSnapshotManifest(
|
|
|
905
905
|
: [],
|
|
906
906
|
)
|
|
907
907
|
if (snapshots.length === 0) return null
|
|
908
|
-
const outPath = path.join(tmpdir(), `
|
|
908
|
+
const outPath = path.join(tmpdir(), `rnx-flow-snapshots-${Date.now()}.json`)
|
|
909
909
|
fs.writeFileSync(outPath, JSON.stringify(snapshots))
|
|
910
910
|
console.log(` flow snapshots: ${snapshots.length} written to ${outPath}`)
|
|
911
911
|
return outPath
|
|
912
912
|
}
|
|
913
913
|
|
|
914
914
|
async function prepareFrameStatsFile(frameStats: unknown): Promise<string> {
|
|
915
|
-
const outPath = path.join(tmpdir(), `
|
|
915
|
+
const outPath = path.join(tmpdir(), `rnx-frame-stats-${Date.now()}.json`)
|
|
916
916
|
fs.writeFileSync(outPath, JSON.stringify(frameStats))
|
|
917
917
|
console.log(` frame stats: written to ${outPath}`)
|
|
918
918
|
return outPath
|
|
@@ -934,7 +934,7 @@ async function runFlowSession(args: string[]) {
|
|
|
934
934
|
case 'keep': {
|
|
935
935
|
const result = keepFlowCandidate()
|
|
936
936
|
if (!result.active) {
|
|
937
|
-
console.error(' no active flow draft — run `
|
|
937
|
+
console.error(' no active flow draft — run `rnx maestro start` first')
|
|
938
938
|
rnxExit(1)
|
|
939
939
|
}
|
|
940
940
|
if (!result.kept) {
|
|
@@ -963,14 +963,14 @@ async function runFlowSession(args: string[]) {
|
|
|
963
963
|
outputPath || (validate ? createDraftValidationPath() : undefined),
|
|
964
964
|
)
|
|
965
965
|
if (!result.active) {
|
|
966
|
-
console.error(' no active flow draft — run `
|
|
966
|
+
console.error(' no active flow draft — run `rnx maestro start` first')
|
|
967
967
|
rnxExit(1)
|
|
968
968
|
}
|
|
969
969
|
if (!result.valid) {
|
|
970
970
|
console.error(' flow draft is not valid:')
|
|
971
971
|
for (const issue of result.issues) console.error(` - ${issue}`)
|
|
972
972
|
console.error(
|
|
973
|
-
' draft preserved — keep at least one real interaction or run `
|
|
973
|
+
' draft preserved — keep at least one real interaction or run `rnx maestro start` to reset',
|
|
974
974
|
)
|
|
975
975
|
rnxExit(1)
|
|
976
976
|
}
|
|
@@ -1005,7 +1005,7 @@ async function runFlowSession(args: string[]) {
|
|
|
1005
1005
|
)
|
|
1006
1006
|
if (result.outputPath) {
|
|
1007
1007
|
console.log(` saved: ${result.outputPath}`)
|
|
1008
|
-
console.log(` next:
|
|
1008
|
+
console.log(` next: rnx maestro test ${result.outputPath} --record`)
|
|
1009
1009
|
return
|
|
1010
1010
|
}
|
|
1011
1011
|
console.log('')
|
|
@@ -1016,7 +1016,7 @@ async function runFlowSession(args: string[]) {
|
|
|
1016
1016
|
case 'validate': {
|
|
1017
1017
|
const flowPath = args[1]
|
|
1018
1018
|
if (!flowPath || flowPath.startsWith('-')) {
|
|
1019
|
-
console.error(' usage:
|
|
1019
|
+
console.error(' usage: rnx maestro validate <path>')
|
|
1020
1020
|
rnxExit(1)
|
|
1021
1021
|
}
|
|
1022
1022
|
const issues = validateFlowFile(flowPath)
|
|
@@ -1033,7 +1033,7 @@ async function runFlowSession(args: string[]) {
|
|
|
1033
1033
|
|
|
1034
1034
|
// the subcommand / flow-file path is the first positional arg, but a
|
|
1035
1035
|
// `--sim <id>` pair can sit in front of it: bin.ts prepends the global
|
|
1036
|
-
// `--sim` to every command's args, and `
|
|
1036
|
+
// `--sim` to every command's args, and `rnx maestro --sim a2 start` is a
|
|
1037
1037
|
// documented form. hoist a leading `--sim <value>` to the end so `args[0]`
|
|
1038
1038
|
// is the real subcommand again (downstream getFlag / parseBridgeCliArgs
|
|
1039
1039
|
// still find `--sim` wherever it lands). without this, `--sim 6a5 flow
|
|
@@ -1071,7 +1071,7 @@ function printFlowProfile(result: SootSimFlowProfileResult) {
|
|
|
1071
1071
|
printShellPerfReport(result)
|
|
1072
1072
|
}
|
|
1073
1073
|
function createDraftValidationPath() {
|
|
1074
|
-
return path.join(tmpdir(), `
|
|
1074
|
+
return path.join(tmpdir(), `rnx-flow-draft-${Date.now()}.yaml`)
|
|
1075
1075
|
}
|
|
1076
1076
|
|
|
1077
1077
|
function buildFlowValidationArgs(args: string[], outputPath: string | null) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// budget and log more aggressively, because an agent can't see mid-animation
|
|
4
4
|
// flicker the way a human can.
|
|
5
5
|
const AGENT_ENV_VARS = [
|
|
6
|
-
'
|
|
6
|
+
'RNX_AGENT',
|
|
7
7
|
'TM_SESSION',
|
|
8
8
|
'CLAUDECODE',
|
|
9
9
|
'CLAUDE_CODE_ENTRYPOINT',
|
|
@@ -14,7 +14,7 @@ const AGENT_ENV_VARS = [
|
|
|
14
14
|
]
|
|
15
15
|
|
|
16
16
|
export function isAgentEnv(): boolean {
|
|
17
|
-
if (process.env.
|
|
17
|
+
if (process.env.RNX_AGENT === '0') return false
|
|
18
18
|
for (const name of AGENT_ENV_VARS) {
|
|
19
19
|
const v = process.env[name]
|
|
20
20
|
if (v && v.trim() && v !== '0') return true
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// `
|
|
1
|
+
// `rnx get-layout` — bounding boxes for visible meaningful elements on the
|
|
2
2
|
// current screen. focused on the layout numbers a designer checks: on-screen
|
|
3
3
|
// box (x/y/w/h). pass --styling for computed borderRadius, per-side padding,
|
|
4
4
|
// fontSize, visual style fields, and native rendered text contrast. pass
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// `
|
|
1
|
+
// `rnx get keyboard` — prints the current iOS keyboard's full state.
|
|
2
2
|
//
|
|
3
3
|
// shows visibility, keyboardType, returnKeyType, autoCapitalize policy,
|
|
4
4
|
// active QWERTY sub-mode, shift + capsLock, and the mounted accessory bar
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// `
|
|
1
|
+
// `rnx get memory` / `rnx debug memory` — per-worker live object
|
|
2
2
|
// counts (nodes registered, pictures, raster images, paragraphs, yoga wasm
|
|
3
3
|
// nodes), image-loader cache, and JS heaps. one-shot by default; --watch
|
|
4
4
|
// samples repeatedly and reports per-counter slope, which is the leak-RCA
|
|
@@ -6,7 +6,7 @@ import type { WsBridge } from '../../ws-bridge'
|
|
|
6
6
|
//
|
|
7
7
|
// pass `positional` from a verb whose positionals are x/y coordinates (tap,
|
|
8
8
|
// double-tap, long-press) and a bare non-numeric first positional reads as a
|
|
9
|
-
// testID: `
|
|
9
|
+
// testID: `rnx do tap my-button` works like `do tap-id my-button` and like
|
|
10
10
|
// `do scroll <id>`, instead of failing with a usage line for the one verb an
|
|
11
11
|
// agent is most likely to reach for. a coordinate is always numeric, so there
|
|
12
12
|
// is nothing to disambiguate.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// `
|
|
1
|
+
// `rnx get screens` — print the current navigation stack + shell state +
|
|
2
2
|
// any presented modal + keyboard. answers "what screen am I on?" without
|
|
3
3
|
// having to dump the whole tree or scrape screen-specific testIDs.
|
|
4
4
|
//
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// `
|
|
1
|
+
// `rnx get tree` — pruned structured semantic tree, default depth 5.
|
|
2
2
|
|
|
3
3
|
import { formatSemanticTree, inspectTree, isSimSemanticTree } from './core'
|
|
4
4
|
import { printJson, wantsJson } from './shared'
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
//
|
|
1
|
+
// rnx wait event — block until a semantic timeline event of the
|
|
2
2
|
// given kind appears, or timeout.
|
|
3
3
|
//
|
|
4
4
|
// usage:
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
5
|
+
// rnx wait event <kind> [--max-ms 5000] [--since now|cursor]
|
|
6
|
+
// rnx wait event fetch [--filter <substring>]
|
|
7
|
+
// rnx wait event screen [--equals SignInPage]
|
|
8
8
|
//
|
|
9
9
|
// the existing wait family is layout-driven: `wait selector` polls
|
|
10
10
|
// for a testID, `wait idle` polls for rAF + animation settling,
|
|
@@ -111,7 +111,7 @@ function eventMatches(
|
|
|
111
111
|
export async function runWaitEventSubcommand(opts: WaitEventOptions): Promise<void> {
|
|
112
112
|
const { bridge, args, positional, inspectUsage } = opts
|
|
113
113
|
// positional shape after verb-prefix strip and stripBooleanFlags:
|
|
114
|
-
//
|
|
114
|
+
// rnx wait event <kind> → ['event', '<kind>']
|
|
115
115
|
// so positional[1] is the kind.
|
|
116
116
|
const kind = positional[1]
|
|
117
117
|
if (!kind) {
|
package/cli/commands/inspect.ts
CHANGED
|
@@ -499,7 +499,7 @@ function printRenderProfile(worker: string, rp: Record<string, any> | undefined)
|
|
|
499
499
|
// pretty-print the shell frame profile payload (__sootsimShellPerf.stop()):
|
|
500
500
|
// per-painted-frame timing from the shell worker merged with the render
|
|
501
501
|
// profile counters. numbers arrive pre-rounded from the worker. also used by
|
|
502
|
-
// `
|
|
502
|
+
// `rnx maestro test --profile`, which records the same payload.
|
|
503
503
|
export function printShellPerfReport(result: Record<string, any>) {
|
|
504
504
|
const fps = result.avgMs > 0 ? (1000 / result.avgMs).toFixed(1) : '?'
|
|
505
505
|
const jank = result.jank && typeof result.jank === 'object' ? result.jank : null
|
|
@@ -1021,9 +1021,9 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
1021
1021
|
// strip a leading grouping verb — `get`, `do`, and (when forwarded from
|
|
1022
1022
|
// runDebug) `debug`. these are organizational prefixes and shouldn't leak
|
|
1023
1023
|
// into subcommand dispatch. e.g.:
|
|
1024
|
-
//
|
|
1025
|
-
//
|
|
1026
|
-
//
|
|
1024
|
+
// rnx get tree → effectiveArgs = ['tree']
|
|
1025
|
+
// rnx do tap 100 200 → effectiveArgs = ['tap', '100', '200']
|
|
1026
|
+
// rnx debug state shell → effectiveArgs = ['state', 'shell']
|
|
1027
1027
|
const verbPrefix =
|
|
1028
1028
|
args[0] === 'get' || args[0] === 'do' || args[0] === 'debug' || args[0] === 'wait'
|
|
1029
1029
|
? args[0]
|
|
@@ -1113,7 +1113,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
1113
1113
|
|
|
1114
1114
|
if (!subcommand || args.includes('--help') || args.includes('-h')) {
|
|
1115
1115
|
// all help output comes from the registry in packages/sootsim-skills
|
|
1116
|
-
// so `
|
|
1116
|
+
// so `rnx do --help`, `rnx get --help`, the website docs, and
|
|
1117
1117
|
// the Contrast skill markdown stay in lock-step. a drift check in
|
|
1118
1118
|
// test/sootsimCliRegistry.test.ts fails CI if a verb lands without a
|
|
1119
1119
|
// matching registry entry.
|
|
@@ -1182,7 +1182,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
1182
1182
|
return
|
|
1183
1183
|
}
|
|
1184
1184
|
|
|
1185
|
-
// `
|
|
1185
|
+
// `rnx list --drivers` — pure local registry view, no bridge needed.
|
|
1186
1186
|
// short-circuit here so users can discover drivers even when no sootsim
|
|
1187
1187
|
// session is running.
|
|
1188
1188
|
if (
|
|
@@ -1730,9 +1730,9 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
1730
1730
|
}
|
|
1731
1731
|
|
|
1732
1732
|
case 'event': {
|
|
1733
|
-
//
|
|
1733
|
+
// rnx wait event <kind> — timeline-backed wait. delegates
|
|
1734
1734
|
// matcher + polling to runWaitEventSubcommand so the same
|
|
1735
|
-
// logic is reachable from `
|
|
1735
|
+
// logic is reachable from `rnx wait event` regardless of
|
|
1736
1736
|
// verb-group prefix (and the same shape is testable on its
|
|
1737
1737
|
// own).
|
|
1738
1738
|
await runWaitEventSubcommand({ bridge, args, positional, inspectUsage })
|
|
@@ -1741,7 +1741,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
1741
1741
|
|
|
1742
1742
|
case 'layout': {
|
|
1743
1743
|
const id = positional[1]
|
|
1744
|
-
// bare `
|
|
1744
|
+
// bare `rnx get layout` (no id) measures visible elements on the
|
|
1745
1745
|
// screen by bounding box. --styling opts into box-model/style detail via
|
|
1746
1746
|
// the shared get-layout kernel the agent's app_get_layout also uses.
|
|
1747
1747
|
// passing an id keeps the single-node {x, y, width, height} lookup.
|
|
@@ -1777,7 +1777,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
1777
1777
|
case 'capture':
|
|
1778
1778
|
case 'screenshot': {
|
|
1779
1779
|
const outputArg = args.find((_, i) => args[i - 1] === '--output')
|
|
1780
|
-
const outputPath = outputArg || '/tmp/
|
|
1780
|
+
const outputPath = outputArg || '/tmp/rnx-inspect.png'
|
|
1781
1781
|
const rect = await resolveSampleRect(args, bridge)
|
|
1782
1782
|
|
|
1783
1783
|
const request: { type: 'screenshot'; crop?: SampleRect } = { type: 'screenshot' }
|
|
@@ -2275,7 +2275,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
2275
2275
|
}
|
|
2276
2276
|
|
|
2277
2277
|
case 'tap-best': {
|
|
2278
|
-
//
|
|
2278
|
+
// rnx do tap-best <query> — try tap-id, then tap-text. the
|
|
2279
2279
|
// common agent ergonomic problem: the agent has a label like
|
|
2280
2280
|
// "Create expense" and doesn't know whether that's a testID
|
|
2281
2281
|
// or visible text. with tap-text it fails when the only
|
|
@@ -2980,8 +2980,8 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
2980
2980
|
|
|
2981
2981
|
case 'state': {
|
|
2982
2982
|
const stateCmd = positional[1]
|
|
2983
|
-
// `
|
|
2984
|
-
// `
|
|
2983
|
+
// `rnx get state` (no sub-arg) → compact runtime dashboard.
|
|
2984
|
+
// `rnx debug state <kind>` continues to dispatch the raw dumps.
|
|
2985
2985
|
if (verbPrefix === 'get' && !stateCmd) {
|
|
2986
2986
|
const base = await callTestBridge<Record<string, any>>(
|
|
2987
2987
|
bridge,
|
|
@@ -4171,20 +4171,20 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
4171
4171
|
}
|
|
4172
4172
|
|
|
4173
4173
|
case 'network': {
|
|
4174
|
-
//
|
|
4174
|
+
// rnx network — live request inspector backed by the shared
|
|
4175
4175
|
// observability store (installed at engine boot, fed by worker-side
|
|
4176
4176
|
// fetch + XHR capture over BroadcastChannel).
|
|
4177
4177
|
//
|
|
4178
4178
|
// shapes:
|
|
4179
|
-
//
|
|
4180
|
-
//
|
|
4181
|
-
//
|
|
4182
|
-
//
|
|
4183
|
-
//
|
|
4184
|
-
//
|
|
4185
|
-
//
|
|
4186
|
-
//
|
|
4187
|
-
//
|
|
4179
|
+
// rnx network [limit] last N entries (default 20)
|
|
4180
|
+
// rnx network --failed only non-2xx / errored
|
|
4181
|
+
// rnx network --slow only requests slower than --threshold (default 1000ms)
|
|
4182
|
+
// rnx network --threshold <ms> customize slow threshold for --slow
|
|
4183
|
+
// rnx network --filter <substring> url substring filter
|
|
4184
|
+
// rnx network --json raw json output
|
|
4185
|
+
// rnx network tail | -f follow mode (polls)
|
|
4186
|
+
// rnx network get <id> detail for one entry
|
|
4187
|
+
// rnx network clear drop the buffer
|
|
4188
4188
|
const sub = positional[1]
|
|
4189
4189
|
|
|
4190
4190
|
// manual flag scan — parseBridgeCliArgs already stripped these
|
|
@@ -4364,17 +4364,17 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
4364
4364
|
}
|
|
4365
4365
|
|
|
4366
4366
|
case 'logs': {
|
|
4367
|
-
//
|
|
4367
|
+
// rnx logs — live console inspector backed by the shared
|
|
4368
4368
|
// observability log store (fed by worker-side console capture over
|
|
4369
|
-
// BroadcastChannel). mirrors `
|
|
4369
|
+
// BroadcastChannel). mirrors `rnx network`:
|
|
4370
4370
|
//
|
|
4371
|
-
//
|
|
4372
|
-
//
|
|
4373
|
-
//
|
|
4374
|
-
//
|
|
4375
|
-
//
|
|
4376
|
-
//
|
|
4377
|
-
//
|
|
4371
|
+
// rnx logs [limit] last N entries (default 50)
|
|
4372
|
+
// rnx logs --level error,warn filter by level (csv)
|
|
4373
|
+
// rnx logs --filter <str> message substring filter
|
|
4374
|
+
// rnx logs --internal include engine-internal [sootsim] logs (hidden by default)
|
|
4375
|
+
// rnx logs --json raw json output
|
|
4376
|
+
// rnx logs tail | -f follow mode (polls)
|
|
4377
|
+
// rnx logs clear drop the buffer
|
|
4378
4378
|
const sub = positional[1]
|
|
4379
4379
|
|
|
4380
4380
|
let filter: string | null = null
|
|
@@ -4493,11 +4493,11 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
4493
4493
|
// auto-settle after any write command so the next CLI call doesn't see
|
|
4494
4494
|
// mid-transition state. short deadline — if the app has a perpetual
|
|
4495
4495
|
// background animation, we bail to layout-only stability via the same
|
|
4496
|
-
// logic `do settle` uses. opt-out: --no-wait or
|
|
4496
|
+
// logic `do settle` uses. opt-out: --no-wait or RNX_NO_AUTO_WAIT=1.
|
|
4497
4497
|
if (
|
|
4498
4498
|
writeCommands.has(subcommand) &&
|
|
4499
4499
|
!args.includes('--no-wait') &&
|
|
4500
|
-
process.env.
|
|
4500
|
+
process.env.RNX_NO_AUTO_WAIT !== '1' &&
|
|
4501
4501
|
!(await shouldSkipAutoSettleForInspectPick(bridge, subcommand))
|
|
4502
4502
|
) {
|
|
4503
4503
|
await autoSettleAfterWrite(bridge)
|
|
@@ -160,7 +160,7 @@ async function installMacDmg(dmgPath: string): Promise<string> {
|
|
|
160
160
|
const userApps = resolve(process.env.HOME || '', 'Applications')
|
|
161
161
|
let destRoot = systemApps
|
|
162
162
|
try {
|
|
163
|
-
const probe = join(systemApps, `.
|
|
163
|
+
const probe = join(systemApps, `.rnx-write-probe-${process.pid}`)
|
|
164
164
|
spawnSync('touch', [probe])
|
|
165
165
|
if (existsSync(probe)) rmSync(probe, { force: true })
|
|
166
166
|
else destRoot = userApps
|
|
@@ -281,7 +281,7 @@ examples:
|
|
|
281
281
|
const skipConfirm =
|
|
282
282
|
args.includes('--yes') ||
|
|
283
283
|
args.includes('-y') ||
|
|
284
|
-
process.env.
|
|
284
|
+
process.env.RNX_NO_PROMPT === '1' ||
|
|
285
285
|
process.env.CI === '1' ||
|
|
286
286
|
!process.stdin.isTTY
|
|
287
287
|
const force = args.includes('--force')
|
|
@@ -318,7 +318,7 @@ examples:
|
|
|
318
318
|
console.log()
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
const workDir = join(tmpdir(), `
|
|
321
|
+
const workDir = join(tmpdir(), `rnx-install-${Date.now()}`)
|
|
322
322
|
const downloadPath = join(workDir, target.filename)
|
|
323
323
|
|
|
324
324
|
let lastDraw = 0
|
package/cli/commands/login.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import { rnxPublicBrand } from '../../src/public-brand'
|
|
9
9
|
import { rnxExit } from '../run-rnx'
|
|
10
10
|
|
|
11
|
-
const REMOTE_DEFAULT_ORIGIN = process.env.
|
|
11
|
+
const REMOTE_DEFAULT_ORIGIN = process.env.RNX_AUTH_ORIGIN || 'https://contrast.dev'
|
|
12
12
|
|
|
13
13
|
type LoginResult =
|
|
14
14
|
| { ok: true; token: string; userId?: string; email?: string }
|
|
@@ -16,8 +16,8 @@ type LoginResult =
|
|
|
16
16
|
|
|
17
17
|
function resolveDefaultAuthOrigin(explicitOrigin?: string) {
|
|
18
18
|
if (explicitOrigin) return explicitOrigin
|
|
19
|
-
if (process.env.
|
|
20
|
-
if (process.env.
|
|
19
|
+
if (process.env.RNX_AUTH_ORIGIN) return process.env.RNX_AUTH_ORIGIN
|
|
20
|
+
if (process.env.RNX_UPLOAD_ORIGIN) return process.env.RNX_UPLOAD_ORIGIN
|
|
21
21
|
return REMOTE_DEFAULT_ORIGIN
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -30,7 +30,7 @@ usage:
|
|
|
30
30
|
|
|
31
31
|
options:
|
|
32
32
|
--origin <url> auth host (default: ${REMOTE_DEFAULT_ORIGIN})
|
|
33
|
-
override with
|
|
33
|
+
override with RNX_AUTH_ORIGIN env var
|
|
34
34
|
-h, --help
|
|
35
35
|
`)
|
|
36
36
|
}
|
|
@@ -114,7 +114,7 @@ function isLocalOrigin(origin: string): boolean {
|
|
|
114
114
|
if (hostname.endsWith('.local')) return true
|
|
115
115
|
if (hostname.endsWith('.localhost')) return true
|
|
116
116
|
// VM↔host bridge aliases — orb, docker, lima, multipass all forward the
|
|
117
|
-
// host on a well-known name (IPv4 or IPv6) so a VM-internal `
|
|
117
|
+
// host on a well-known name (IPv4 or IPv6) so a VM-internal `rnx login`
|
|
118
118
|
// can still take the dev-login fast path against the host's Contrast dev
|
|
119
119
|
// server. without this the CLI falls through to a browser callback that
|
|
120
120
|
// is unreachable from a headless VM.
|
|
@@ -253,7 +253,7 @@ export async function runLogin(args: string[]) {
|
|
|
253
253
|
return
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
const url = new URL(`${origin.replace(/\/$/, '')}/auth/
|
|
256
|
+
const url = new URL(`${origin.replace(/\/$/, '')}/auth/rnx-cli`)
|
|
257
257
|
url.searchParams.set('state', state)
|
|
258
258
|
url.searchParams.set('port', String(address.port))
|
|
259
259
|
url.searchParams.set('contrast', origin)
|