rnxsim 0.1.335 → 0.1.337
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 +104 -76
- package/cli/auth.ts +2 -2
- package/cli/bin.ts +7 -3
- package/cli/bridge-flow-runner.ts +2 -2
- package/cli/commands/agent-wrapper.ts +1 -1
- package/cli/commands/agent.ts +12 -12
- package/cli/commands/app-fonts.ts +1 -1
- package/cli/commands/assert.ts +7 -7
- package/cli/commands/auth.ts +4 -4
- package/cli/commands/camera.ts +13 -13
- package/cli/commands/cleanup.ts +6 -6
- package/cli/commands/compat.ts +4 -4
- package/cli/commands/config.ts +2 -2
- package/cli/commands/control.ts +37 -43
- package/cli/commands/cpu-profile.ts +2 -2
- package/cli/commands/daemon-mac-app.ts +2 -2
- package/cli/commands/daemon.ts +12 -12
- package/cli/commands/debug.ts +22 -22
- package/cli/commands/desktop.ts +3 -3
- package/cli/commands/detox.ts +17 -17
- package/cli/commands/device.ts +9 -9
- package/cli/commands/diagnose.ts +11 -11
- package/cli/commands/electron.ts +7 -7
- package/cli/commands/film.ts +6 -6
- package/cli/commands/inspect/core.ts +6 -7
- package/cli/commands/inspect/find.ts +2 -2
- package/cli/commands/inspect.ts +36 -36
- package/cli/commands/install-desktop.ts +8 -8
- package/cli/commands/login.ts +6 -6
- package/cli/commands/maestro-generate.ts +2 -2
- package/cli/commands/maestro.ts +23 -23
- package/cli/commands/mode.ts +4 -4
- package/cli/commands/no-bridge-hint.ts +9 -9
- package/cli/commands/perf.ts +11 -11
- package/cli/commands/permissions.ts +5 -5
- package/cli/commands/profile.ts +11 -11
- package/cli/commands/react.ts +15 -15
- package/cli/commands/record.ts +15 -15
- package/cli/commands/report-issue.ts +2 -2
- package/cli/commands/reset.ts +2 -2
- package/cli/commands/runtime.ts +18 -18
- package/cli/commands/screenshot-mode.ts +5 -5
- package/cli/commands/screenshot.ts +12 -12
- package/cli/commands/screenshots-capture.ts +7 -7
- package/cli/commands/screenshots.ts +6 -6
- package/cli/commands/serve.ts +6 -6
- package/cli/commands/setup.ts +13 -15
- package/cli/commands/skills.ts +14 -14
- package/cli/commands/slides.ts +19 -23
- package/cli/commands/state.ts +2 -2
- package/cli/commands/storage.ts +3 -3
- package/cli/commands/telemetry.ts +1 -1
- package/cli/commands/three-mode.ts +16 -16
- package/cli/commands/timeline.ts +4 -4
- package/cli/commands/upgrade.ts +1 -1
- package/cli/commands/upload.ts +11 -11
- package/cli/commands/version.ts +3 -5
- package/cli/commands/what-happened.ts +11 -11
- package/cli/drivers/electron.ts +3 -3
- package/cli/hints.ts +8 -8
- package/cli/recording-access.ts +1 -1
- package/cli/ws-bridge.ts +5 -5
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-XSJMAFVA.js → agent-QQ3RJNRY.js} +14 -14
- package/dist-cli/chunks/{agent-wrapper-NFLJ5K64.js → agent-wrapper-M6SQSMRY.js} +3 -3
- package/dist-cli/chunks/app-fonts-F6NDV3XC.js +4 -0
- package/dist-cli/chunks/{assert-ILAXIYB5.js → assert-5VB3KQNK.js} +12 -12
- package/dist-cli/chunks/auth-PFXODKFN.js +12 -0
- package/dist-cli/chunks/{beta-TDR6UKJU.js → beta-WUWYHT4F.js} +2 -2
- package/dist-cli/chunks/camera-V3MMTKP7.js +33 -0
- package/dist-cli/chunks/{chunk-INBPUR4T.js → chunk-2ANFH72P.js} +11 -11
- package/dist-cli/chunks/chunk-2GIA5T6B.js +74 -0
- package/dist-cli/chunks/{chunk-GP6QEBZA.js → chunk-4FRSEZ7Z.js} +1 -1
- package/dist-cli/chunks/{chunk-USGOQ3YJ.js → chunk-4GXBZHNA.js} +2 -2
- package/dist-cli/chunks/{chunk-R3CMECGC.js → chunk-4HESY5E7.js} +4 -4
- package/dist-cli/chunks/{chunk-WKT7YM5Q.js → chunk-4VJEXQGD.js} +1 -1
- package/dist-cli/chunks/{chunk-FE6ZHPKD.js → chunk-5LJNNHZH.js} +1 -1
- package/dist-cli/chunks/{chunk-I2HQB5NN.js → chunk-5QXGSTYI.js} +2 -2
- package/dist-cli/chunks/{chunk-FJSHIWAM.js → chunk-5SHAOQHJ.js} +2 -2
- package/dist-cli/chunks/{chunk-CGZWLSYD.js → chunk-5UPRBMIG.js} +1 -1
- package/dist-cli/chunks/{chunk-ZTM2MKNI.js → chunk-5ZEFRPCC.js} +1 -1
- package/dist-cli/chunks/{chunk-RTD3CPDQ.js → chunk-6ART4XVJ.js} +23 -23
- package/dist-cli/chunks/{chunk-MTD6IAEA.js → chunk-6CAUT2LH.js} +1 -1
- package/dist-cli/chunks/{chunk-ZYHCWCMM.js → chunk-7ATIH7OU.js} +1 -1
- package/dist-cli/chunks/{chunk-RVUGKXJD.js → chunk-7Q4QKHMA.js} +1 -1
- package/dist-cli/chunks/{chunk-MTNIDSOA.js → chunk-ABK2V2PR.js} +1 -1
- package/dist-cli/chunks/{chunk-TL4DNDDY.js → chunk-B53ILAHI.js} +2 -2
- package/dist-cli/chunks/{chunk-POC3QTA6.js → chunk-BSSVLFZR.js} +2 -2
- package/dist-cli/chunks/chunk-BVOBXTPN.js +30 -0
- package/dist-cli/chunks/{chunk-4KC35DMK.js → chunk-CPDEUWL5.js} +2 -2
- package/dist-cli/chunks/{chunk-HNQLZZJA.js → chunk-DINU267S.js} +2 -2
- package/dist-cli/chunks/{chunk-DCDKJ4NC.js → chunk-DQQ4CZVC.js} +2 -2
- package/dist-cli/chunks/{chunk-JWAY6DIH.js → chunk-EDWN2HOO.js} +18 -18
- package/dist-cli/chunks/{chunk-3CS4EUMG.js → chunk-EWVG4A3B.js} +2 -2
- package/dist-cli/chunks/{chunk-RTEJXUXN.js → chunk-F3NKCQHM.js} +6 -6
- package/dist-cli/chunks/{chunk-M7CBQ5I4.js → chunk-GEAGFYKP.js} +1 -1
- package/dist-cli/chunks/chunk-GGNH44PZ.js +5 -0
- package/dist-cli/chunks/{chunk-YSUIYK6B.js → chunk-HAHJJJUC.js} +2 -2
- package/dist-cli/chunks/chunk-HPJ5EKIZ.js +4 -0
- package/dist-cli/chunks/{chunk-IN2PZBQD.js → chunk-IBTHGFKE.js} +2 -2
- package/dist-cli/chunks/{chunk-ZZWO6Y7X.js → chunk-J6BYRRZQ.js} +2 -2
- package/dist-cli/chunks/{chunk-6Y3PVPTF.js → chunk-JK4OZ2TQ.js} +5 -5
- package/dist-cli/chunks/{chunk-PO3TOAED.js → chunk-KGQAO25M.js} +2 -2
- package/dist-cli/chunks/{chunk-J7XFINJG.js → chunk-L6UUIQE7.js} +2 -2
- package/dist-cli/chunks/{chunk-35XNGT5C.js → chunk-LXYLCETR.js} +1 -1
- package/dist-cli/chunks/{chunk-JWK5WD44.js → chunk-LZAL3DMP.js} +2 -2
- package/dist-cli/chunks/{chunk-3ZDOPKHE.js → chunk-M43UU7UG.js} +4 -4
- package/dist-cli/chunks/{chunk-ROPHZJ6P.js → chunk-M4LGUVBM.js} +2 -2
- package/dist-cli/chunks/{chunk-RELRA5VW.js → chunk-NCG6C5AH.js} +2 -2
- package/dist-cli/chunks/{chunk-42KDXJUD.js → chunk-NR5TSR2Y.js} +2 -2
- package/dist-cli/chunks/{chunk-R2UL5VFY.js → chunk-OCPWXT73.js} +3 -3
- package/dist-cli/chunks/{chunk-VV4MXLFR.js → chunk-ODKS6JUJ.js} +1 -1
- package/dist-cli/chunks/{chunk-F33DUJGG.js → chunk-R2WBREGQ.js} +1 -1
- package/dist-cli/chunks/chunk-RKY3ZNTA.js +5 -0
- package/dist-cli/chunks/{chunk-MGGRL2Z2.js → chunk-SW7BHOMO.js} +9 -9
- package/dist-cli/chunks/{chunk-GVKISFQ3.js → chunk-TJTLXG3R.js} +1 -1
- package/dist-cli/chunks/chunk-TNI4PW75.js +124 -0
- package/dist-cli/chunks/{chunk-CL3PREIE.js → chunk-UWEDNDND.js} +2 -2
- package/dist-cli/chunks/{chunk-IV36DY6M.js → chunk-WRID5SBV.js} +1 -1
- package/dist-cli/chunks/{chunk-42ALI64M.js → chunk-WUYI3XJ5.js} +2 -2
- package/dist-cli/chunks/{chunk-6VN5ULGQ.js → chunk-X7MHCEGG.js} +2 -2
- package/dist-cli/chunks/chunk-XIQFYLWD.js +15 -0
- package/dist-cli/chunks/{chunk-LCVUJCRJ.js → chunk-ZUK5ZQU7.js} +1 -1
- package/dist-cli/chunks/{cleanup-X6ZRPFDV.js → cleanup-6WBS3MUO.js} +10 -10
- package/dist-cli/chunks/cli-version-HUQCDGMA.js +4 -0
- package/dist-cli/chunks/{compat-VRXJ5J56.js → compat-2WOPKJYK.js} +9 -9
- package/dist-cli/chunks/{config-LHPPE4EP.js → config-FPD7WUYB.js} +5 -5
- package/dist-cli/chunks/{control-TVTNGSSF.js → control-B3XNER7I.js} +2 -2
- package/dist-cli/chunks/daemon-T4D4X2P5.js +4 -0
- package/dist-cli/chunks/{debug-EUHBBPGM.js → debug-LKV5CEAV.js} +17 -17
- package/dist-cli/chunks/desktop-EMDPOYQT.js +31 -0
- package/dist-cli/chunks/detox-4J4UTZE7.js +52 -0
- package/dist-cli/chunks/{device-PONITUZJ.js → device-PMZ7RPXQ.js} +11 -11
- package/dist-cli/chunks/{diagnose-2PN4K4L2.js → diagnose-MLEP727D.js} +12 -12
- package/dist-cli/chunks/{disk-cleanup-U2PQLOEW.js → disk-cleanup-CVEDIPEE.js} +2 -2
- package/dist-cli/chunks/drivers-NTUKJEL6.js +4 -0
- package/dist-cli/chunks/{film-XGZCFTQL.js → film-4RNECABF.js} +9 -9
- package/dist-cli/chunks/flow-5IOCAHVO.js +4 -0
- package/dist-cli/chunks/help-NUJUYEWP.js +4 -0
- package/dist-cli/chunks/{hidden-runtime-alias-I4MYF5CO.js → hidden-runtime-alias-YIF25W4F.js} +2 -2
- package/dist-cli/chunks/{home-paths-YRAPZ5LE.js → home-paths-WNJCCCCZ.js} +2 -2
- package/dist-cli/chunks/inspect-MFEIYUCN.js +4 -0
- package/dist-cli/chunks/install-desktop-NB65KI4D.js +4 -0
- package/dist-cli/chunks/{login-ZMAIAQ6F.js → login-VEHHGN42.js} +6 -6
- package/dist-cli/chunks/{logout-UQZ5JBJU.js → logout-VE7PNXL2.js} +2 -2
- package/dist-cli/chunks/{maestro-BQYKDUC4.js → maestro-ZXHTDEOI.js} +25 -25
- package/dist-cli/chunks/{maestro-generate-VQYMMQJ5.js → maestro-generate-TK33E2Z6.js} +3 -3
- package/dist-cli/chunks/mode-ZDKJ56NT.js +26 -0
- package/dist-cli/chunks/{optional-demo-registry-DUWHCLGD.js → optional-demo-registry-GBZ3WVDW.js} +2 -2
- package/dist-cli/chunks/{perf-7RAU7WRZ.js → perf-JXNZOUKW.js} +28 -28
- package/dist-cli/chunks/permissions-WQ62PW7Y.js +13 -0
- package/dist-cli/chunks/record-4S3ZMDIO.js +72 -0
- package/dist-cli/chunks/{report-issue-P376KFFU.js → report-issue-KKBADTWO.js} +4 -4
- package/dist-cli/chunks/reset-H5XIISJE.js +4 -0
- package/dist-cli/chunks/runtime-FK7EEMWA.js +4 -0
- package/dist-cli/chunks/{screenshot-command-NE7BKTQ2.js → screenshot-command-42U5MVQL.js} +34 -34
- package/dist-cli/chunks/{screenshot-layers-UE4R64PZ.js → screenshot-layers-4G42AHOX.js} +2 -2
- package/dist-cli/chunks/{screenshots-capture-ULXPLXMC.js → screenshots-capture-HMQ2OO3I.js} +11 -11
- package/dist-cli/chunks/{serve-P7BT4XHR.js → serve-S4V5EDW2.js} +16 -16
- package/dist-cli/chunks/setup-T43V7GA6.js +32 -0
- package/dist-cli/chunks/{skills-NTRYKJSF.js → skills-O426K26J.js} +16 -16
- package/dist-cli/chunks/{state-4D5YAM47.js → state-ZEEPDKJG.js} +5 -5
- package/dist-cli/chunks/storage-4GQLOFGG.js +37 -0
- package/dist-cli/chunks/store-RFMSNWLJ.js +4 -0
- package/dist-cli/chunks/telemetry-NFAAPSMN.js +4 -0
- package/dist-cli/chunks/{timeline-GZNFGD3Q.js → timeline-ONCYX7KW.js} +6 -6
- package/dist-cli/chunks/{upgrade-A46D6PEY.js → upgrade-A36T52AM.js} +2 -2
- package/dist-cli/chunks/upload-36O32DII.js +4 -0
- package/dist-cli/chunks/version-67HA253N.js +6 -0
- package/dist-cli/chunks/{web-H2IXO5SC.js → web-PWXQHQIE.js} +2 -2
- package/dist-cli/chunks/{what-happened-Z7UII5GH.js → what-happened-WNXE622R.js} +16 -16
- package/dist-lib/agent-daemon-client.cjs +5 -5
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +4 -4
- 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 +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 +7 -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/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +248 -98
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +2 -2
- package/dist-lib/menu.mjs +2 -2
- package/dist-lib/metro-host-modules/react-dom.js +6 -0
- package/dist-lib/metro-host-modules/react-native-web.js +6 -0
- package/dist-lib/metro-host-modules/react-native.js +6 -0
- package/dist-lib/metro-host-modules/react.js +6 -0
- package/dist-lib/metro-host-modules/react__jsx-dev-runtime.js +6 -0
- package/dist-lib/metro-host-modules/react__jsx-runtime.js +6 -0
- package/dist-lib/metro-production-bundle.cjs +72 -0
- package/dist-lib/metro-production-bundle.mjs +44 -0
- package/dist-lib/metro.cjs +152 -8
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +2 -2
- package/dist-lib/react-native-host-modules.cjs +50 -0
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +6 -7
- package/dist-lib/sdk.mjs +6 -7
- package/dist-lib/skills.cjs +71 -77
- package/dist-lib/vite.cjs +104 -85
- package/package.json +15 -2
- package/scripts/preuninstall.cjs +1 -1
- package/skills/contrast/SKILL.md +67 -75
- package/skills/rnx-debug/SKILL.md +84 -84
- package/skills/rnx-perf/SKILL.md +8 -8
- package/skills/rnx-setup/SKILL.md +54 -54
- package/skills/rnx-test/SKILL.md +35 -35
- package/skills/rnx-visual/SKILL.md +18 -18
- package/src/agent-daemon-client.ts +2 -2
- package/src/agent-sessions.ts +2 -2
- package/src/connect.ts +6 -6
- package/src/disk-cleanup.ts +1 -1
- package/src/home-paths.ts +1 -1
- package/src/host/bridge-host.ts +6 -6
- package/src/index.ts +1 -1
- package/src/metro-host-modules/react-dom.js +6 -0
- package/src/metro-host-modules/react-native-web.js +6 -0
- package/src/metro-host-modules/react-native.js +6 -0
- package/src/metro-host-modules/react.js +6 -0
- package/src/metro-host-modules/react__jsx-dev-runtime.js +6 -0
- package/src/metro-host-modules/react__jsx-runtime.js +6 -0
- package/src/metro-plugin.ts +249 -10
- package/src/metro-production-bundle.ts +51 -0
- package/src/public-brand.ts +1 -1
- package/src/react-native-host-modules.ts +25 -0
- package/src/runtime-assets.ts +1 -1
- package/src/sim-client.ts +1 -1
- package/src/vite-plugin-one.ts +171 -145
- package/dist-cli/chunks/app-fonts-L3UXFYVE.js +0 -4
- package/dist-cli/chunks/auth-ISX2EUQL.js +0 -12
- package/dist-cli/chunks/camera-4SWTNJUA.js +0 -33
- package/dist-cli/chunks/chunk-BRHZEZKN.js +0 -124
- package/dist-cli/chunks/chunk-EJPYPJWP.js +0 -5
- package/dist-cli/chunks/chunk-KWCD5MOK.js +0 -15
- package/dist-cli/chunks/chunk-MJ7QGY7Z.js +0 -4
- package/dist-cli/chunks/chunk-RSA4XWHN.js +0 -5
- package/dist-cli/chunks/chunk-S3EIOAWZ.js +0 -74
- package/dist-cli/chunks/chunk-TYANJQLO.js +0 -30
- package/dist-cli/chunks/cli-version-NZUSWKZR.js +0 -4
- package/dist-cli/chunks/daemon-XUEC47EC.js +0 -4
- package/dist-cli/chunks/desktop-LLHMP4A3.js +0 -31
- package/dist-cli/chunks/detox-QLNWLXA4.js +0 -52
- package/dist-cli/chunks/drivers-7IU37M2E.js +0 -4
- package/dist-cli/chunks/flow-NZZLR4BN.js +0 -4
- package/dist-cli/chunks/help-D7URIJRD.js +0 -4
- package/dist-cli/chunks/inspect-TJYWKY56.js +0 -4
- package/dist-cli/chunks/install-desktop-LD3W5RS7.js +0 -4
- package/dist-cli/chunks/mode-ZQ6H7KWM.js +0 -26
- package/dist-cli/chunks/permissions-DRZ3HCFL.js +0 -13
- package/dist-cli/chunks/record-J5JAYW4Y.js +0 -72
- package/dist-cli/chunks/reset-KXYRDEFU.js +0 -4
- package/dist-cli/chunks/runtime-66CEPOG6.js +0 -4
- package/dist-cli/chunks/setup-QO5KZAX3.js +0 -32
- package/dist-cli/chunks/storage-X2K2MDPX.js +0 -37
- package/dist-cli/chunks/store-TUJPIRTT.js +0 -4
- package/dist-cli/chunks/telemetry-CF5DVEKI.js +0 -4
- package/dist-cli/chunks/upload-UIQJIBEZ.js +0 -4
- package/dist-cli/chunks/version-CMBB3FXL.js +0 -6
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ tarball, fetched from the contrast.dev CDN and unpacked into `~/.sootsim`.
|
|
|
14
14
|
|
|
15
15
|
What this package gives you:
|
|
16
16
|
|
|
17
|
-
- the `
|
|
17
|
+
- the `rnx` CLI — the primary debugging and automation surface (inspect the
|
|
18
18
|
UI tree, tap elements, capture flows, screenshot, record, run agents)
|
|
19
19
|
- `rnxsim/vite` and `rnxsim/metro` — bundler plugins that serve the installed
|
|
20
20
|
engine runtime from your own dev server
|
|
@@ -52,7 +52,7 @@ internally splits into shell, compositor, and tenant workers.
|
|
|
52
52
|
|
|
53
53
|
```mermaid
|
|
54
54
|
graph TD
|
|
55
|
-
subgraph cli["
|
|
55
|
+
subgraph cli["rnx CLI process (short-lived, cli/)"]
|
|
56
56
|
BIN["bin.ts (dispatcher + telemetry)"]
|
|
57
57
|
SETUP["commands/setup.ts (guided daemon setup)"]
|
|
58
58
|
RUNTIMECMD["commands/runtime.ts (runtime install/use)"]
|
|
@@ -132,11 +132,11 @@ graph TD
|
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
**The CLI process** (`cli/bin.ts`) parses argv, emits invocation telemetry, and
|
|
135
|
-
lazy-imports exactly one command module per run. Bare `
|
|
136
|
-
`
|
|
135
|
+
lazy-imports exactly one command module per run. Bare `rnx` and
|
|
136
|
+
`rnx setup` own guided one-time machine work: ask which package manager you
|
|
137
137
|
use for app commands, explain repo-pinned Node versions, recommend a global
|
|
138
138
|
`rnxsim` install, and install the faster background daemon when it is
|
|
139
|
-
missing. `
|
|
139
|
+
missing. `rnx open`
|
|
140
140
|
ensures the engine runtime exists and starts a local foreground bridge when no
|
|
141
141
|
daemon is reachable, then opens a `WsBridge` (`cli/ws-bridge.ts`) on **port
|
|
142
142
|
7668** and sends JSON commands. Inspection/interaction verbs live in
|
|
@@ -147,7 +147,7 @@ Browser sims launch in an isolated Playwright Chrome for Testing profile;
|
|
|
147
147
|
Electron is the native desktop surface.
|
|
148
148
|
|
|
149
149
|
**The daemon is one process** — `SootSimBridgeHost` (`src/host/bridge-host.ts`).
|
|
150
|
-
`
|
|
150
|
+
`rnx serve` runs it in the foreground; the background daemon is the *same
|
|
151
151
|
process* wrapped with autostart and the `~/.sootsim/daemon.json` lockfile. It is
|
|
152
152
|
an HTTP+WS hub: sims register over WS, CLI clients connect to drive them, and
|
|
153
153
|
the host forwards each command to the targeted sim and relays the reply back. It
|
|
@@ -170,10 +170,11 @@ bridge always addresses the **shell worker**, never an undifferentiated sim.
|
|
|
170
170
|
|
|
171
171
|
**Two distinct plugin families** round it out, and they must not be conflated:
|
|
172
172
|
|
|
173
|
-
- The published **`rnxsim/vite`** (`src/vite-plugin-one.ts`, `
|
|
173
|
+
- The published **`rnxsim/vite`** (`src/vite-plugin-one.ts`, `rnxPlugin`)
|
|
174
174
|
and **`rnxsim/metro`** plugins do one thing: serve the installed runtime at
|
|
175
|
-
`/__soot/` so an app's own dev server can host the sim shell
|
|
176
|
-
|
|
175
|
+
`/__soot/` so an app's own dev server can host the sim shell. The vite
|
|
176
|
+
plugin's `open: true` option also launches the simulator when the dev server
|
|
177
|
+
starts (skipped when `CI` or `SOOTSIM_NO_OPEN` is set).
|
|
177
178
|
- The internal **`sootsim()`** plugin (`src/vite-plugin.ts`) is a separate, much
|
|
178
179
|
larger RN-resolution / native-stub plugin: it aliases `react-native` to the
|
|
179
180
|
engine shim and native packages to `@sootsim/compat` stubs, applies worklets
|
|
@@ -185,58 +186,58 @@ bridge always addresses the **shell worker**, never an undifferentiated sim.
|
|
|
185
186
|
|
|
186
187
|
| component | role | key files |
|
|
187
188
|
| --- | --- | --- |
|
|
188
|
-
|
|
|
189
|
+
| rnx CLI (bin + dispatcher) | Short-lived terminal entry point. Parses argv, emits telemetry, lazy-imports one command per run, and routes guided setup/open/runtime/inspection flows without a hidden bootstrap path. | `cli/bin.ts`, `cli/parse-args.ts`, `cli/help.ts`, `cli/commands/setup.ts`, `cli/commands/control.ts` |
|
|
189
190
|
| WsBridge client | Client side of the CLI→daemon link. Resolves the daemon port from the lockfile, opens a WS to `:7668`, sends JSON commands and awaits `{id,result}`/`{id,error}`. Used by every interactive command. | `cli/ws-bridge.ts`, `src/bridge-constants.ts`, `cli/current-sim.ts` |
|
|
190
191
|
| inspect / SDK command surface | Runtime inspection + interaction verbs (describe, find, do tap, get errors, wait, layout, settle). Re-exported as `rnxsim/sdk` so programmatic callers drive a sim the same way the CLI does. | `cli/commands/inspect/core.ts`, `cli/commands/inspect/actions.ts`, `cli/commands/inspect.ts`, `src/sdk.ts` |
|
|
191
192
|
| Maestro / Detox runners | Drop-in test compatibility. `bridge-flow-runner.ts` runs Maestro YAML and recorded flows over the bridge; `detox/` provides a `by`/`element`/`expect`/`device` driver + jest preset so existing Detox suites run unchanged. | `cli/bridge-flow-runner.ts`, `cli/commands/maestro.ts`, `cli/commands/detox.ts`, `detox/index.ts`, `detox/jest-preset.cjs` |
|
|
192
193
|
| sim drivers | Launch or attach the actual sim page. Playwright owns isolated browser profiles; Electron owns the native desktop surface. The current sim is reused unless `--new`, `--profile`, or `--ephemeral` requests a separate one. | `cli/drivers/index.ts`, `cli/drivers/registry.ts`, `cli/drivers/electron.ts`, `cli/drivers/playwright.ts` |
|
|
193
|
-
| SootSimBridgeHost (serve/daemon) | The bridge process (`
|
|
194
|
+
| SootSimBridgeHost (serve/daemon) | The bridge process (`rnx serve`, or autostarted as the daemon via launchd/systemd). HTTP+WS hub on `:7668`: relays commands between CLI clients and registered sims; also serves runtime HTTP, `/__server-scan`, and fetch/WS proxies. | `src/host/bridge-host.ts`, `cli/commands/serve.ts`, `cli/commands/daemon.ts`, `src/home-paths.ts` |
|
|
194
195
|
| AgentHost + sessions | Agent-routing extension of the host: owns the single FIFO reader per agent session and fans `agent:event`/`session-status` pushes to every WS subscriber. Backed by agent-sessions + attached-projects stores. | `src/host/agent-host.ts`, `src/agent-sessions.ts`, `src/attached-projects.ts`, `src/agent-daemon-client.ts` |
|
|
195
196
|
| host proxies + dev-server scan | Host-side helpers so a cross-origin tenant worker can reach local dev servers and same-origin APIs: `/__server-scan` discovers running metro/expo/vxrn/one servers; fetch + websocket proxies relay guest-app network through the daemon. | `src/host/fetch-proxy-handler.ts`, `src/host/websocket-proxy.ts`, `scripts/dev-server-scanner.ts`, `src/dev-bundle-resolution.ts` |
|
|
196
197
|
| runtime delivery + rnx home | Versioned engine runtime management. The shared machinery owns manifest fetch, sha256 verification, channels, and auto-update. rnx binds it to `https://contrast.dev` and `~/.sootsim/runtimes/<version>`. A repo can select `runtimeVersion` without changing the machine default. | `src/runtime-delivery.ts`, `packages/contrast-runtime-delivery/`, `src/home-paths.ts`, `src/runtime-assets.ts`, `scripts/postinstall.cjs` |
|
|
197
198
|
| `rnxsim/vite` + `rnxsim/metro` (runtime serving) | Published bundler plugins. Both serve the installed engine runtime at `/__soot/` from `~/.sootsim/runtimes/<version>` so an app's own dev server can host the sim shell; the vite plugin can also launch the Electron app. | `src/vite-plugin-one.ts`, `src/metro-plugin.ts`, `src/runtime-assets.ts` |
|
|
198
199
|
| `sootsim()` vite resolver plugin (internal) | The large RN-resolution / native-stub vite plugin: aliases `react-native` to the engine shim, native packages to `@sootsim/compat` stubs, applies worklets/babel transforms, and instantiates `SootSimBridgeHost` in its dev server. Distinct from the published `rnxsim/vite` export. | `src/vite-plugin.ts`, `src/worklets-babel.ts`, `packages/compat/src/stub-manifest.ts` |
|
|
199
|
-
| skills registry | rnx agent skills (`rnx-setup`, `rnx-debug`, `rnx-test`, `rnx-visual`, and the generated `contrast` index) installable with `
|
|
200
|
+
| skills registry | rnx agent skills (`rnx-setup`, `rnx-debug`, `rnx-test`, `rnx-visual`, and the generated `contrast` index) installable with `rnx skill`. | `skills/*.md`, `src/skills/registry.ts`, `src/skills/types.ts` |
|
|
200
201
|
|
|
201
202
|
## Getting started
|
|
202
203
|
|
|
203
204
|
```sh
|
|
204
205
|
curl -fsSL https://rnxsim.com/install.sh | sh
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
206
|
+
rnx setup # guided one-time machine setup
|
|
207
|
+
rnx open 8081 # load a running metro/expo dev server
|
|
208
|
+
rnx open /settings # dispatch a React Native deep link into that app
|
|
208
209
|
```
|
|
209
210
|
|
|
210
|
-
The first `
|
|
211
|
+
The first `rnx open` launches an isolated Chrome for Testing sim. The CLI
|
|
211
212
|
resolves Playwright from the app or CLI install, asks that exact package for
|
|
212
213
|
its required browser executable, and runs that package's installer once when
|
|
213
214
|
the executable is absent. It never substitutes another revision found in the
|
|
214
215
|
shared Playwright cache. Later opens reuse that sim and reload it at the
|
|
215
|
-
requested target. Use `
|
|
216
|
+
requested target. Use `rnx do reload` when the target has not changed.
|
|
216
217
|
Reserve `--new` for a genuinely concurrent sim; repeated new browser trees
|
|
217
218
|
consume memory and CPU on shared machines.
|
|
218
219
|
|
|
219
220
|
The public shell script is the recommended, inspectable bootstrap path;
|
|
220
|
-
`
|
|
221
|
+
`rnx` is the normal path afterward. Manual installs can use `npm install
|
|
221
222
|
--global rnxsim`, `bun add --global rnxsim`, or `pnpm add --global rnxsim`,
|
|
222
|
-
followed by `
|
|
223
|
+
followed by `rnx setup`. There is no per-app install:
|
|
223
224
|
start your Metro, Expo, or One dev server the way you already do, then open it
|
|
224
225
|
from the CLI. There is no iOS native build in the inner loop; Metro alone is
|
|
225
|
-
enough. `
|
|
226
|
+
enough. `rnx open` starts a local bridge when no daemon is reachable; the
|
|
226
227
|
guided setup installs the faster background daemon so later CLI commands reuse
|
|
227
|
-
one server. A desktop GUI (Electron) is optional on top, via `
|
|
228
|
-
install`. Native Electron windows created by `
|
|
229
|
-
session and close when the session exits; `
|
|
228
|
+
one server. A desktop GUI (Electron) is optional on top, via `rnx desktop
|
|
229
|
+
install`. Native Electron windows created by `rnx open` belong to that CLI
|
|
230
|
+
session and close when the session exits; `rnx desktop` keeps the persistent
|
|
230
231
|
desktop-app lifecycle. In Electron, `File > New Window`
|
|
231
232
|
duplicates the focused simulator, while `File > New Simulator >` opens a new
|
|
232
233
|
window for a selected device (same device list as the `Window >` menu).
|
|
233
234
|
|
|
234
235
|
To uninstall the machine daemon and cached runtimes, run
|
|
235
|
-
`
|
|
236
|
+
`rnx daemon uninstall`. It stops current and legacy launchd / systemd
|
|
236
237
|
services, removes daemon logs, and removes `~/.sootsim/` (runtimes, profiles,
|
|
237
238
|
recordings, and lockfiles). It does not remove the optional
|
|
238
239
|
`/Applications/sootsim.app` desktop bundle or macOS preference plist. To inspect
|
|
239
|
-
existing disk usage before uninstalling, run `
|
|
240
|
+
existing disk usage before uninstalling, run `rnx cleanup`; add `--apply`
|
|
240
241
|
only after reviewing the preview.
|
|
241
242
|
|
|
242
243
|
## Jump to source in inspect mode
|
|
@@ -270,54 +271,81 @@ inspection, interaction, animation debugging, shell tracing, screenshots, and
|
|
|
270
271
|
flow capture, not just as a test runner.
|
|
271
272
|
|
|
272
273
|
```sh
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
274
|
+
rnx list # connected tabs
|
|
275
|
+
rnx open 8081 # load a running metro/expo dev server
|
|
276
|
+
rnx open /settings # route via React Native Linking
|
|
277
|
+
rnx describe # dump UI tree
|
|
278
|
+
rnx get errors 5 # recent runtime failures
|
|
279
|
+
rnx compat # scan native package compatibility
|
|
280
|
+
rnx report-issue "…" # preview an opt-in compatibility report
|
|
281
|
+
rnx find --testid cta # inspect one node deeply
|
|
282
|
+
rnx debug enable animated,layout
|
|
283
|
+
rnx debug trace shell on 240
|
|
284
|
+
rnx do tap-text "..." # interact
|
|
285
|
+
rnx debug snapshot before
|
|
286
|
+
rnx debug snapshot after
|
|
287
|
+
rnx debug diff before after
|
|
288
|
+
rnx maestro start # begin a Maestro draft
|
|
289
|
+
rnx maestro keep # persist the last action
|
|
290
|
+
rnx maestro end --output .maestro/login.yaml --validate
|
|
291
|
+
rnx detox # run Detox/Jest suites against rnx
|
|
291
292
|
```
|
|
292
293
|
|
|
293
|
-
See the full command reference via `
|
|
294
|
+
See the full command reference via `rnx --help` or at
|
|
294
295
|
`src/features/site/docs/rnx/cli/` in the Contrast repo.
|
|
295
296
|
|
|
296
297
|
Sim-scoped commands use the primary fallback only when one driveable sim is
|
|
297
298
|
connected. With multiple driveable sims, the bridge lists their ids and refuses
|
|
298
|
-
to choose. Run `
|
|
299
|
+
to choose. Run `rnx use <id>` to pin later commands, or pass `--sim <id>` to
|
|
299
300
|
target one command.
|
|
300
301
|
|
|
301
302
|
## Bundler plugins (`rnxsim/vite` and `rnxsim/metro`)
|
|
302
303
|
|
|
303
|
-
|
|
304
|
-
**not** resolve React Native or stub native modules — that is the internal
|
|
305
|
-
`sootsim()` plugin's job (see Architecture).
|
|
304
|
+
The Vite plugin serves the installed RNX runtime from your existing dev server.
|
|
306
305
|
|
|
307
306
|
```ts
|
|
308
307
|
// vite.config.ts
|
|
309
|
-
import {
|
|
308
|
+
import { rnxPlugin } from 'rnxsim/vite'
|
|
310
309
|
|
|
311
310
|
export default {
|
|
312
|
-
plugins: [
|
|
311
|
+
plugins: [rnxPlugin()],
|
|
313
312
|
}
|
|
314
313
|
```
|
|
315
314
|
|
|
316
315
|
```js
|
|
317
316
|
// metro.config.js
|
|
318
|
-
const {
|
|
317
|
+
const { getDefaultConfig } = require('expo/metro-config')
|
|
318
|
+
const { withRNX } = require('rnxsim/metro')
|
|
319
319
|
|
|
320
|
-
|
|
320
|
+
const config = getDefaultConfig(__dirname)
|
|
321
|
+
|
|
322
|
+
module.exports = withRNX(config, { devServer: true })
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
The Metro wrapper has two independent opt-ins. `devServer` serves the RNX shell
|
|
326
|
+
from the Metro process. `productionBundles` lets explicitly marked production
|
|
327
|
+
bundle requests use the RNX host implementations of React and React Native
|
|
328
|
+
while the rest of the app receives production transforms.
|
|
329
|
+
|
|
330
|
+
```js
|
|
331
|
+
module.exports = withRNX(config, { productionBundles: true })
|
|
332
|
+
|
|
333
|
+
// enable both when the same Metro process should provide both integrations
|
|
334
|
+
module.exports = withRNX(config, {
|
|
335
|
+
devServer: true,
|
|
336
|
+
productionBundles: true,
|
|
337
|
+
})
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Calling `withRNX(config)` changes nothing. Production requests must run in a
|
|
341
|
+
Metro process started with `NODE_ENV=production` and use the URL helper:
|
|
342
|
+
|
|
343
|
+
```js
|
|
344
|
+
const { toRNXProductionBundleUrl } = require('rnxsim/metro')
|
|
345
|
+
|
|
346
|
+
const bundleUrl = toRNXProductionBundleUrl(
|
|
347
|
+
'http://localhost:8081/index.bundle?platform=ios',
|
|
348
|
+
)
|
|
321
349
|
```
|
|
322
350
|
|
|
323
351
|
## Coming from Detox
|
|
@@ -334,8 +362,8 @@ no code changes — just add one line to your jest config:
|
|
|
334
362
|
Or use the CLI directly:
|
|
335
363
|
|
|
336
364
|
```sh
|
|
337
|
-
|
|
338
|
-
|
|
365
|
+
rnx detox # auto-discovers e2e/ tests and launches a shell
|
|
366
|
+
rnx detox init # scaffold a config + sample test
|
|
339
367
|
```
|
|
340
368
|
|
|
341
369
|
See `../../docs/migrating-from-detox.md` for details.
|
|
@@ -346,10 +374,10 @@ Maestro is rnx's single YAML test surface. Point it at your existing
|
|
|
346
374
|
`.maestro/` directory, generate a test, or author one from live actions:
|
|
347
375
|
|
|
348
376
|
```sh
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
377
|
+
rnx maestro # discover .maestro/ and run all flows
|
|
378
|
+
rnx maestro test .maestro/ # explicit
|
|
379
|
+
rnx maestro generate "verify login"
|
|
380
|
+
rnx maestro --list-compat # see the verb support matrix
|
|
353
381
|
```
|
|
354
382
|
|
|
355
383
|
Most Maestro verbs work out of the box (`tapOn`, `assertVisible`, `inputText`,
|
|
@@ -362,22 +390,22 @@ need real device hardware (GPS, radio, photo library) throw a clear error. See
|
|
|
362
390
|
For animation-heavy debugging, the useful path is usually:
|
|
363
391
|
|
|
364
392
|
```sh
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
393
|
+
rnx debug enable animated
|
|
394
|
+
rnx debug trace shell on 240
|
|
395
|
+
rnx debug snapshot before
|
|
368
396
|
# reproduce the transition
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
397
|
+
rnx debug snapshot after
|
|
398
|
+
rnx debug diff before after
|
|
399
|
+
rnx screenshot --with-frame --output /tmp/sootsim-framed.png
|
|
400
|
+
rnx record --duration 5 --output /tmp/sootsim-anim.mp4
|
|
373
401
|
```
|
|
374
402
|
|
|
375
|
-
`
|
|
403
|
+
`rnx screenshot --with-frame` composes the real rnx shell device chrome
|
|
376
404
|
around the raw screen bitmap (reusing the shell bezel/button geometry, excluding
|
|
377
405
|
the Electron top bar, rail gutter, and other window chrome). Flows can request
|
|
378
406
|
the framed export inline without changing Maestro syntax:
|
|
379
407
|
|
|
380
|
-
`
|
|
408
|
+
`rnx wait ready` and the screenshot readiness guard accept inspectable
|
|
381
409
|
native content, a populated node tree, or a live-frame channel whose publish
|
|
382
410
|
count advances across probes. Canvas-only GL, WebGPU, and video surfaces can
|
|
383
411
|
therefore prove that they are painting without weakening the boot-card guard.
|
|
@@ -389,7 +417,7 @@ therefore prove that they are painting without weakening the boot-card guard.
|
|
|
389
417
|
withFrame: true
|
|
390
418
|
```
|
|
391
419
|
|
|
392
|
-
For plan-driven app-store exports, use `
|
|
420
|
+
For plan-driven app-store exports, use `rnx screenshot appstore`:
|
|
393
421
|
|
|
394
422
|
```yaml
|
|
395
423
|
app: 8081
|
|
@@ -412,14 +440,14 @@ compose:
|
|
|
412
440
|
```
|
|
413
441
|
|
|
414
442
|
```sh
|
|
415
|
-
|
|
443
|
+
rnx screenshot appstore --plan .sootsim/app-store.yaml
|
|
416
444
|
```
|
|
417
445
|
|
|
418
446
|
The plan runner can reuse a visible sim for capture (`--sim a9`), stop after
|
|
419
447
|
raw/framed intermediates (`--capture-only`), or rerender final marketing
|
|
420
448
|
canvases from an existing raw directory (`--compose-only`). If your flow already
|
|
421
449
|
writes screenshots to explicit project paths, set `from:` + `pathMode: flow` so
|
|
422
|
-
`
|
|
450
|
+
`rnx screenshot appstore` respects the flow's own `takeScreenshot` paths
|
|
423
451
|
instead of prepending `--screenshots <rawDir>`:
|
|
424
452
|
|
|
425
453
|
```yaml
|
|
@@ -436,7 +464,7 @@ frame for quick art-direction passes.
|
|
|
436
464
|
|
|
437
465
|
## Skills registry
|
|
438
466
|
|
|
439
|
-
`
|
|
467
|
+
`rnx skill install` installs rnx agent skills in the standard
|
|
440
468
|
`<skill-name>/SKILL.md` layout used by Codex and Claude Code. The bundled
|
|
441
469
|
skills cover setup, debugging/perf/accessibility, testing, visual review, and
|
|
442
470
|
the generated `contrast` command index. The published CLI registry and generated
|
|
@@ -475,7 +503,7 @@ verifies its sha256, and unpacks it under `~/.sootsim`:
|
|
|
475
503
|
```
|
|
476
504
|
|
|
477
505
|
The bridge daemon serves these assets over HTTP and exposes a self-update route;
|
|
478
|
-
`
|
|
506
|
+
`rnx upgrade` / `rnx runtime` drive explicit version changes from the
|
|
479
507
|
CLI side. Installation retains the active runtime plus one rollback and removes
|
|
480
508
|
the downloaded archive after extraction. Disposable Playwright caches live in a
|
|
481
509
|
bounded per-session temporary directory; Electron's persistent HTTP cache is
|
|
@@ -483,11 +511,11 @@ disabled for simulator profiles and globally capped for app chrome. Cookies,
|
|
|
483
511
|
localStorage, IndexedDB, service workers, recordings, and captured frames are
|
|
484
512
|
user-owned data and are not removed by the default cleanup command.
|
|
485
513
|
|
|
486
|
-
Per-repo configuration is optional. Every installed-runtime `
|
|
514
|
+
Per-repo configuration is optional. Every installed-runtime `rnx open`
|
|
487
515
|
serves its selected version from a version-specific localhost origin, so a
|
|
488
516
|
background activation cannot mix an already loaded shell with chunks from the
|
|
489
517
|
next runtime. Without config, each new open selects the active stable version.
|
|
490
|
-
When `sootsim.config.ts` sets `runtimeVersion`, `
|
|
518
|
+
When `sootsim.config.ts` sets `runtimeVersion`, `rnx open` installs that
|
|
491
519
|
version without changing the machine default. Running from a monorepo root
|
|
492
520
|
resolves the only React Native app from package workspaces, then shares that app
|
|
493
521
|
root across config, font, and splash discovery. The fallback scan is bounded and
|
|
@@ -499,7 +527,7 @@ maintenance process. The app and terminal command are usable before the legacy
|
|
|
499
527
|
filesystem scan begins. The worker prints the reclaimed size to stderr, records
|
|
500
528
|
completion, and does not run the scan again. Open browser profiles and a runtime
|
|
501
529
|
served by a live daemon or development bridge are left untouched. The automatic
|
|
502
|
-
pass retries on a later command after they close. The explicit `
|
|
530
|
+
pass retries on a later command after they close. The explicit `rnx cleanup --aggressive`
|
|
503
531
|
command remains the only path that removes the rollback runtime or user-created
|
|
504
532
|
recordings.
|
|
505
533
|
|
|
@@ -512,6 +540,6 @@ bun run build:cli
|
|
|
512
540
|
```
|
|
513
541
|
|
|
514
542
|
The output is `dist-cli/bin.js` — a single esbuild output published as the
|
|
515
|
-
`rnxsim` npm bin. Library exports build to `dist-lib/` (consumed via the
|
|
543
|
+
`rnx` (and `rnxsim`) npm bin. Library exports build to `dist-lib/` (consumed via the
|
|
516
544
|
`exports` map: `.`, `./vite`, `./metro`, `./sdk`, `./skills`, `./detox`, and the
|
|
517
545
|
host/agent helpers). `bun run pack:smoke` validates the publishable tarball.
|
package/cli/auth.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// 1. RNX_API_KEY, or SOOTSIM_API_KEY if that is unset — ci path
|
|
5
5
|
// 2. CONTRAST_INSTALLATION_TOKEN/GITHUB_TOKEN + repo env — github action
|
|
6
6
|
// preview uploads from the Contrast runner, no extra secret
|
|
7
|
-
// 3. desktop session token from shared desktop auth (`
|
|
7
|
+
// 3. desktop session token from shared desktop auth (`rnx login`)
|
|
8
8
|
//
|
|
9
9
|
// callers wanting an auth header: `authHeaderOrExit('upload')`.
|
|
10
10
|
|
|
@@ -148,7 +148,7 @@ export function authHeaderOrExit(commandLabel: string): {
|
|
|
148
148
|
process.stderr.write(
|
|
149
149
|
`\n rnx ${commandLabel} needs to be authenticated.\n\n` +
|
|
150
150
|
` pick one:\n` +
|
|
151
|
-
` • run \`
|
|
151
|
+
` • run \`rnx login\` to sign in with your GH account\n` +
|
|
152
152
|
` • set RNX_API_KEY=sk_rnx_... (recommended for CI)\n\n`,
|
|
153
153
|
)
|
|
154
154
|
process.exit(1)
|
package/cli/bin.ts
CHANGED
|
@@ -196,7 +196,7 @@ if (parsed.version) {
|
|
|
196
196
|
const { getCliVersion } = await import('../src/cli-version')
|
|
197
197
|
const { IS_BETA, BETA_LABEL } = await import('../src/beta')
|
|
198
198
|
const suffix = IS_BETA ? ` · ${BETA_LABEL}` : ''
|
|
199
|
-
console.log(
|
|
199
|
+
console.log(`${rnxPublicBrand.commandName} v${getCliVersion()}${suffix}`)
|
|
200
200
|
// runtime version on its own line — keeps the first line parseable while
|
|
201
201
|
// surfacing the (independently-versioned) engine runtime users actually
|
|
202
202
|
// render with. see `sootsim upgrade`.
|
|
@@ -262,7 +262,9 @@ if (!command) {
|
|
|
262
262
|
const attempted =
|
|
263
263
|
parsed.commandArgs.find((a) => !a.startsWith('-')) ?? parsed.commandArgs[0]
|
|
264
264
|
console.error(` unknown command: ${attempted}`)
|
|
265
|
-
console.error(
|
|
265
|
+
console.error(
|
|
266
|
+
` run \`${rnxPublicBrand.commandName} --help\` to see the full surface.`,
|
|
267
|
+
)
|
|
266
268
|
await exitWithFlush(1)
|
|
267
269
|
}
|
|
268
270
|
const { printHelp } = await import('./help')
|
|
@@ -578,7 +580,9 @@ if (TOP_LEVEL_RUNTIME_COMMANDS.has(command)) {
|
|
|
578
580
|
|
|
579
581
|
default: {
|
|
580
582
|
console.error(` unknown command: ${command}`)
|
|
581
|
-
console.error(
|
|
583
|
+
console.error(
|
|
584
|
+
` run \`${rnxPublicBrand.commandName} --help\` to see the full surface.`,
|
|
585
|
+
)
|
|
582
586
|
await exitWithFlush(1)
|
|
583
587
|
}
|
|
584
588
|
}
|
|
@@ -608,8 +608,8 @@ export class SootSimBridgeFlowRunner {
|
|
|
608
608
|
if (consecutiveBridgeFailures >= 4) {
|
|
609
609
|
throw new Error(
|
|
610
610
|
`target sim is not responding to the bridge (${lastError.message}). ` +
|
|
611
|
-
`it is likely a stale orphan — run \`
|
|
612
|
-
`with \`
|
|
611
|
+
`it is likely a stale orphan — run \`rnx list\`, then close it ` +
|
|
612
|
+
`with \`rnx close <id>\` or start a fresh one with \`rnx open --new <port>\`.`,
|
|
613
613
|
)
|
|
614
614
|
}
|
|
615
615
|
await this.refreshSimId()
|
|
@@ -131,7 +131,7 @@ export async function runAgentWrapper(argv: string[]): Promise<number> {
|
|
|
131
131
|
!args.eventsOut
|
|
132
132
|
) {
|
|
133
133
|
process.stderr.write(
|
|
134
|
-
'usage:
|
|
134
|
+
'usage: rnx agent-wrapper --session-id <id> --project-id <id>\n' +
|
|
135
135
|
' --provider codex|claude --cwd <path>\n' +
|
|
136
136
|
' --prompt-in <fifo> --events-out <fifo>\n' +
|
|
137
137
|
' [--transcript <file>]\n' +
|
package/cli/commands/agent.ts
CHANGED
|
@@ -140,7 +140,7 @@ async function cmdAttach(argv: string[]): Promise<number> {
|
|
|
140
140
|
const dir = positional[0]
|
|
141
141
|
if (!dir) {
|
|
142
142
|
process.stderr.write(
|
|
143
|
-
'usage:
|
|
143
|
+
'usage: rnx agent attach <dir> [--name X] [--provider codex|claude]\n',
|
|
144
144
|
)
|
|
145
145
|
return 2
|
|
146
146
|
}
|
|
@@ -167,7 +167,7 @@ async function cmdAttach(argv: string[]): Promise<number> {
|
|
|
167
167
|
async function cmdProjects(): Promise<number> {
|
|
168
168
|
const projects = [...listProjects()].sort((a, b) => b.updatedAt - a.updatedAt)
|
|
169
169
|
if (projects.length === 0) {
|
|
170
|
-
process.stdout.write('no attached projects yet. try `
|
|
170
|
+
process.stdout.write('no attached projects yet. try `rnx agent attach <dir>`.\n')
|
|
171
171
|
return 0
|
|
172
172
|
}
|
|
173
173
|
const header = `${'ID'.padEnd(18)} ${'NAME'.padEnd(20)} ${'FRAMEWORK'.padEnd(10)} ${'PROVIDER'.padEnd(8)} ${'7D COST'.padEnd(10)} CWD\n`
|
|
@@ -186,7 +186,7 @@ async function cmdProject(argv: string[]): Promise<number> {
|
|
|
186
186
|
const [action, id] = argv
|
|
187
187
|
if (action === 'show') {
|
|
188
188
|
if (!id) {
|
|
189
|
-
process.stderr.write('usage:
|
|
189
|
+
process.stderr.write('usage: rnx agent project show <id>\n')
|
|
190
190
|
return 2
|
|
191
191
|
}
|
|
192
192
|
const project = findProjectById(id)
|
|
@@ -199,14 +199,14 @@ async function cmdProject(argv: string[]): Promise<number> {
|
|
|
199
199
|
}
|
|
200
200
|
if (action === 'remove') {
|
|
201
201
|
if (!id) {
|
|
202
|
-
process.stderr.write('usage:
|
|
202
|
+
process.stderr.write('usage: rnx agent project remove <id>\n')
|
|
203
203
|
return 2
|
|
204
204
|
}
|
|
205
205
|
deleteProject(id)
|
|
206
206
|
process.stdout.write(`✓ removed project ${id}\n`)
|
|
207
207
|
return 0
|
|
208
208
|
}
|
|
209
|
-
process.stderr.write('usage:
|
|
209
|
+
process.stderr.write('usage: rnx agent project [show|remove] <id>\n')
|
|
210
210
|
return 2
|
|
211
211
|
}
|
|
212
212
|
|
|
@@ -247,7 +247,7 @@ async function cmdStart(argv: string[]): Promise<number> {
|
|
|
247
247
|
const projectId = positional[0]
|
|
248
248
|
if (!projectId) {
|
|
249
249
|
process.stderr.write(
|
|
250
|
-
'usage:
|
|
250
|
+
'usage: rnx agent start <projectId> [--provider codex|claude] [--fresh-thread]\n',
|
|
251
251
|
)
|
|
252
252
|
return 2
|
|
253
253
|
}
|
|
@@ -268,8 +268,8 @@ async function cmdStart(argv: string[]): Promise<number> {
|
|
|
268
268
|
` project: ${project.name} (${project.id})\n` +
|
|
269
269
|
` provider: ${result.session.provider}\n` +
|
|
270
270
|
` pid: ${result.wrapperPid}\n` +
|
|
271
|
-
` prompt with:
|
|
272
|
-
` watch events:
|
|
271
|
+
` prompt with: rnx agent prompt ${result.session.id} "<text>"\n` +
|
|
272
|
+
` watch events: rnx agent watch ${result.session.id}\n`,
|
|
273
273
|
)
|
|
274
274
|
return 0
|
|
275
275
|
}
|
|
@@ -278,7 +278,7 @@ async function cmdPrompt(argv: string[]): Promise<number> {
|
|
|
278
278
|
const [sessionId, ...rest] = argv
|
|
279
279
|
const text = rest.join(' ')
|
|
280
280
|
if (!sessionId || !text) {
|
|
281
|
-
process.stderr.write('usage:
|
|
281
|
+
process.stderr.write('usage: rnx agent prompt <sessionId> "<text>"\n')
|
|
282
282
|
return 2
|
|
283
283
|
}
|
|
284
284
|
await withDaemon((client) => client.sendPrompt(sessionId, { text }))
|
|
@@ -289,7 +289,7 @@ async function cmdPrompt(argv: string[]): Promise<number> {
|
|
|
289
289
|
async function cmdWatch(argv: string[]): Promise<number> {
|
|
290
290
|
const sessionId = argv[0]
|
|
291
291
|
if (!sessionId) {
|
|
292
|
-
process.stderr.write('usage:
|
|
292
|
+
process.stderr.write('usage: rnx agent watch <sessionId>\n')
|
|
293
293
|
return 2
|
|
294
294
|
}
|
|
295
295
|
process.stdout.write(`watching ${sessionId}\n---\n`)
|
|
@@ -363,7 +363,7 @@ function formatEvent(ev: AgentEvent): string {
|
|
|
363
363
|
async function cmdTranscript(argv: string[]): Promise<number> {
|
|
364
364
|
const sessionId = argv[0]
|
|
365
365
|
if (!sessionId) {
|
|
366
|
-
process.stderr.write('usage:
|
|
366
|
+
process.stderr.write('usage: rnx agent transcript <sessionId>\n')
|
|
367
367
|
return 2
|
|
368
368
|
}
|
|
369
369
|
const p = transcriptPath(sessionId)
|
|
@@ -378,7 +378,7 @@ async function cmdTranscript(argv: string[]): Promise<number> {
|
|
|
378
378
|
async function cmdEnd(argv: string[]): Promise<number> {
|
|
379
379
|
const sessionId = argv[0]
|
|
380
380
|
if (!sessionId) {
|
|
381
|
-
process.stderr.write('usage:
|
|
381
|
+
process.stderr.write('usage: rnx agent end <sessionId>\n')
|
|
382
382
|
return 2
|
|
383
383
|
}
|
|
384
384
|
await withDaemon((client) => client.endSession(sessionId))
|
|
@@ -38,7 +38,7 @@ async function stage(args: string[]): Promise<void> {
|
|
|
38
38
|
const manifestPath = flag(args, 'manifest')
|
|
39
39
|
if (!outDir || !manifestPath) {
|
|
40
40
|
console.error(
|
|
41
|
-
' usage:
|
|
41
|
+
' usage: rnx app-fonts stage --wire <wire> --out-dir <dir> --manifest <path>',
|
|
42
42
|
)
|
|
43
43
|
process.exit(1)
|
|
44
44
|
}
|
package/cli/commands/assert.ts
CHANGED
|
@@ -501,10 +501,10 @@ function sleep(ms: number): Promise<void> {
|
|
|
501
501
|
|
|
502
502
|
function printHelp(): void {
|
|
503
503
|
process.stdout.write(`
|
|
504
|
-
|
|
504
|
+
rnx assert — run any read verb and convert its output into a bisect-friendly exit code.
|
|
505
505
|
|
|
506
506
|
usage:
|
|
507
|
-
|
|
507
|
+
rnx assert <verb> <verb-args...> <assertion-flags...>
|
|
508
508
|
|
|
509
509
|
exit codes:
|
|
510
510
|
0 assertion passed (git bisect: good)
|
|
@@ -532,10 +532,10 @@ assertion flags (AND'd when multiple are given):
|
|
|
532
532
|
--quiet suppress the one-line pass/fail summary
|
|
533
533
|
|
|
534
534
|
examples:
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
535
|
+
rnx assert find --testid set-max-input --count 4
|
|
536
|
+
rnx assert describe --contains "swap-form-header"
|
|
537
|
+
rnx assert get errors --count 0
|
|
538
|
+
rnx assert find --testid submit --exists --within 3000
|
|
539
|
+
rnx assert describe --jq '.shell.state == "app"'
|
|
540
540
|
`)
|
|
541
541
|
}
|
package/cli/commands/auth.ts
CHANGED
|
@@ -3,13 +3,13 @@ import { resolveCliAuth } from '../auth'
|
|
|
3
3
|
|
|
4
4
|
function printHelp(): void {
|
|
5
5
|
console.log(`
|
|
6
|
-
|
|
6
|
+
rnx auth — inspect CLI auth
|
|
7
7
|
|
|
8
8
|
usage:
|
|
9
|
-
|
|
9
|
+
rnx auth
|
|
10
10
|
|
|
11
11
|
API keys are read from RNX_API_KEY, or SOOTSIM_API_KEY if that is unset.
|
|
12
|
-
Use \`
|
|
12
|
+
Use \`rnx login\` to sign in and \`rnx logout\` to clear the desktop session.
|
|
13
13
|
`)
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -17,7 +17,7 @@ async function printStatus(): Promise<number> {
|
|
|
17
17
|
const auth = resolveCliAuth()
|
|
18
18
|
if (!auth) {
|
|
19
19
|
console.log(' not signed in')
|
|
20
|
-
console.log(' set RNX_API_KEY=sk_rnx_... or run `
|
|
20
|
+
console.log(' set RNX_API_KEY=sk_rnx_... or run `rnx login`')
|
|
21
21
|
return 1
|
|
22
22
|
}
|
|
23
23
|
|