rnxsim 0.1.352 → 0.1.353
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 +17 -16
- package/cli/bin.ts +5 -4
- package/cli/commands/control.ts +20 -5
- package/cli/commands/daemon-mac-app.ts +1 -1
- package/cli/commands/daemon.ts +6 -8
- package/cli/commands/install-desktop.ts +42 -32
- package/cli/commands/no-bridge-hint.ts +3 -3
- package/cli/commands/serve.ts +1 -1
- package/cli/commands/setup.ts +215 -176
- package/cli/commands/welcome.ts +9 -58
- package/cli/desktop-companion.ts +31 -16
- package/cli/prompt.ts +12 -7
- package/cli/setup-repository.ts +6 -2
- package/cli/ui.ts +68 -0
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-27WDUXK5.js → agent-YTAX6OQQ.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-XAUWPZ6O.js → agent-wrapper-2QSUXMNK.js} +2 -2
- package/dist-cli/chunks/{app-fonts-COAZFLDG.js → app-fonts-4EVHPXVG.js} +2 -2
- package/dist-cli/chunks/{assert-ZR2UE3EH.js → assert-IXMSQLVY.js} +2 -2
- package/dist-cli/chunks/{auth-LISHWKCC.js → auth-6QFWU2T5.js} +2 -2
- package/dist-cli/chunks/{beta-AQQUYVA5.js → beta-27I5WWRE.js} +2 -2
- package/dist-cli/chunks/{camera-KE44ZN3U.js → camera-4HFUBXPM.js} +2 -2
- package/dist-cli/chunks/{chunk-DJAYEBF3.js → chunk-37J74ASV.js} +1 -1
- package/dist-cli/chunks/{chunk-XI4W6LRQ.js → chunk-3IWR7KHR.js} +2 -2
- package/dist-cli/chunks/{chunk-CY6HBAOB.js → chunk-3UXMNDMH.js} +2 -2
- package/dist-cli/chunks/{chunk-R2BFC3AC.js → chunk-3XDGLCNP.js} +2 -2
- package/dist-cli/chunks/{chunk-6NSUY346.js → chunk-4IXIONDR.js} +2 -2
- package/dist-cli/chunks/{chunk-YAMKV3UB.js → chunk-4NPZ5FO2.js} +2 -2
- package/dist-cli/chunks/{chunk-QJTW4QQW.js → chunk-4PV6QASJ.js} +1 -1
- package/dist-cli/chunks/{chunk-PEBQKBEP.js → chunk-57YZEJ6J.js} +1 -1
- package/dist-cli/chunks/{chunk-4AOAJXE2.js → chunk-5DLBRZAG.js} +2 -2
- package/dist-cli/chunks/{chunk-7T7DR34H.js → chunk-6JBOKETZ.js} +2 -2
- package/dist-cli/chunks/{chunk-AR3CPCW3.js → chunk-6NE5Z6KG.js} +1 -1
- package/dist-cli/chunks/{chunk-RASWCAJJ.js → chunk-7FUSVOMH.js} +2 -2
- package/dist-cli/chunks/{chunk-5JE5PNIV.js → chunk-7SKQRS74.js} +1 -1
- package/dist-cli/chunks/chunk-7V5O6I4Q.js +9 -0
- package/dist-cli/chunks/{chunk-3Y7NWE22.js → chunk-BK5TJXUU.js} +2 -2
- package/dist-cli/chunks/{chunk-H4IF54WS.js → chunk-CMQIFA4L.js} +1 -1
- package/dist-cli/chunks/{chunk-3ZV4WSCR.js → chunk-CYS3D7RG.js} +2 -2
- package/dist-cli/chunks/{chunk-LRKODRWI.js → chunk-DSBUGNC5.js} +2 -2
- package/dist-cli/chunks/{chunk-EGKGCDG5.js → chunk-ECIDT6F5.js} +1 -1
- package/dist-cli/chunks/{chunk-EHQHK7KN.js → chunk-ELBDKQK2.js} +2 -2
- package/dist-cli/chunks/{chunk-ELNSQ352.js → chunk-GAYCF2O5.js} +1 -1
- package/dist-cli/chunks/{chunk-ESVF72YH.js → chunk-HVLZYUGF.js} +2 -2
- package/dist-cli/chunks/{chunk-5JINX2IB.js → chunk-HWMBTYJX.js} +2 -2
- package/dist-cli/chunks/{chunk-MJB6N7WS.js → chunk-HZTWQZUD.js} +2 -2
- package/dist-cli/chunks/{chunk-M6DC6JZL.js → chunk-IX7W5BXL.js} +2 -2
- package/dist-cli/chunks/{chunk-BZ32JGFC.js → chunk-JVVO63QH.js} +1 -1
- package/dist-cli/chunks/{chunk-JEPQ5YX3.js → chunk-KIQVNLVD.js} +2 -2
- package/dist-cli/chunks/chunk-KZLGVYCX.js +7 -0
- package/dist-cli/chunks/{chunk-QP7KGSU4.js → chunk-LAFKQUT7.js} +3 -3
- package/dist-cli/chunks/{chunk-E42ZJLPN.js → chunk-LMFAIAA5.js} +1 -1
- package/dist-cli/chunks/chunk-MA5E6HJR.js +15 -0
- package/dist-cli/chunks/chunk-OEU2MEZQ.js +124 -0
- package/dist-cli/chunks/{chunk-BQE4E24T.js → chunk-PBTG4UCS.js} +1 -1
- package/dist-cli/chunks/{chunk-XHZEKHB2.js → chunk-PNQ33FJB.js} +6 -6
- package/dist-cli/chunks/{chunk-MJJP2BEI.js → chunk-R4KBCGXX.js} +3 -3
- package/dist-cli/chunks/chunk-RMOSWLWG.js +32 -0
- package/dist-cli/chunks/{chunk-WNJDE2JT.js → chunk-RRX5RZI2.js} +1 -1
- package/dist-cli/chunks/{chunk-R4P7WO4L.js → chunk-T2ZZSSCP.js} +2 -2
- package/dist-cli/chunks/{chunk-DSF4WC4X.js → chunk-TX2T5KPQ.js} +2 -2
- package/dist-cli/chunks/{chunk-2OME2KGY.js → chunk-UEILOAPW.js} +1 -1
- package/dist-cli/chunks/{chunk-TF6VBUZ7.js → chunk-UNBVUOIC.js} +2 -2
- package/dist-cli/chunks/chunk-UQBXA3AK.js +24 -0
- package/dist-cli/chunks/{chunk-H6MTPXZS.js → chunk-V7X543SB.js} +1 -1
- package/dist-cli/chunks/{chunk-45D2GGIA.js → chunk-VLI54BKH.js} +2 -2
- package/dist-cli/chunks/{chunk-RH6FJI5O.js → chunk-VZDW2U64.js} +2 -2
- package/dist-cli/chunks/chunk-WKQ6W74M.js +11 -0
- package/dist-cli/chunks/{chunk-S2PJOB2C.js → chunk-WTGQUQ32.js} +2 -2
- package/dist-cli/chunks/{chunk-P5YC5VGA.js → chunk-WU25RTIX.js} +2 -2
- package/dist-cli/chunks/chunk-WV3TKN7D.js +4 -0
- package/dist-cli/chunks/{chunk-Q4ROOH3W.js → chunk-XVLYLZOM.js} +2 -2
- package/dist-cli/chunks/{chunk-VQDY7NEJ.js → chunk-YQJOM55S.js} +1 -1
- package/dist-cli/chunks/{chunk-AIGZ3TSW.js → chunk-YYYWU6LL.js} +3 -3
- package/dist-cli/chunks/{chunk-NQMZOJPX.js → chunk-ZF53H457.js} +2 -2
- package/dist-cli/chunks/{chunk-24CIPQT5.js → chunk-ZJ4O636U.js} +1 -1
- package/dist-cli/chunks/{chunk-ZK5HYQ4I.js → chunk-ZXHAAVTH.js} +2 -2
- package/dist-cli/chunks/{chunk-FHLEA4S5.js → chunk-ZYGWIVW4.js} +2 -2
- package/dist-cli/chunks/{cleanup-JUY2WU24.js → cleanup-ULH3BHAE.js} +2 -2
- package/dist-cli/chunks/cli-version-I2E56I4W.js +4 -0
- package/dist-cli/chunks/{compat-S2TBISY3.js → compat-ONN5DOHB.js} +2 -2
- package/dist-cli/chunks/{config-3PHD4J5N.js → config-OPZU73MX.js} +2 -2
- package/dist-cli/chunks/control-WNYEAI4K.js +4 -0
- package/dist-cli/chunks/daemon-5J6V2GLG.js +4 -0
- package/dist-cli/chunks/{debug-PFAJONVV.js → debug-GNI3HDAK.js} +3 -3
- package/dist-cli/chunks/{desktop-Z7EOBMNV.js → desktop-DF65PDJG.js} +4 -4
- package/dist-cli/chunks/{detox-KRSP5SLY.js → detox-N267KW2Y.js} +2 -2
- package/dist-cli/chunks/{device-ZXJ7GRBO.js → device-RFU44PE3.js} +2 -2
- package/dist-cli/chunks/{diagnose-JIMLEOEJ.js → diagnose-XR2JIGDE.js} +2 -2
- package/dist-cli/chunks/{disk-cleanup-YY7FFGVA.js → disk-cleanup-DPY6TYXA.js} +2 -2
- package/dist-cli/chunks/drivers-OIZC544W.js +4 -0
- package/dist-cli/chunks/{film-LKSJPU2A.js → film-NQQZPZ2W.js} +3 -3
- package/dist-cli/chunks/flow-3NHEHRF4.js +4 -0
- package/dist-cli/chunks/help-VACWNWEH.js +4 -0
- package/dist-cli/chunks/{hidden-runtime-alias-ZN3WZ3ND.js → hidden-runtime-alias-APCBIXJ6.js} +2 -2
- package/dist-cli/chunks/home-paths-27GY5EPD.js +4 -0
- package/dist-cli/chunks/inspect-2JELKZ5A.js +4 -0
- package/dist-cli/chunks/install-desktop-4R7UTGQU.js +4 -0
- package/dist-cli/chunks/{login-XKLIFTAU.js → login-6KIO5FR4.js} +2 -2
- package/dist-cli/chunks/{logout-DR22RB5H.js → logout-WMCYGTYA.js} +2 -2
- package/dist-cli/chunks/{maestro-SLCX6HBV.js → maestro-7QLOUZIE.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-GBFZ5INV.js → maestro-generate-QIGCQANR.js} +3 -3
- package/dist-cli/chunks/{mode-F4R2KNXX.js → mode-3H662MUJ.js} +2 -2
- package/dist-cli/chunks/{optional-demo-registry-HM55KXGB.js → optional-demo-registry-FQV54ASP.js} +2 -2
- package/dist-cli/chunks/{perf-VBS5GEPG.js → perf-KC6LOGFD.js} +2 -2
- package/dist-cli/chunks/{permissions-F46PQIUE.js → permissions-UGVHA3L6.js} +2 -2
- package/dist-cli/chunks/privacy-E6KH2DRJ.js +4 -0
- package/dist-cli/chunks/{record-NLZ6DFAA.js → record-V72Q363I.js} +3 -3
- package/dist-cli/chunks/{report-issue-XIE5BVR4.js → report-issue-MILOOCMG.js} +2 -2
- package/dist-cli/chunks/reset-LEL5ZGFN.js +4 -0
- package/dist-cli/chunks/runtime-RT2OTIQC.js +4 -0
- package/dist-cli/chunks/{screenshot-command-SD4JPNKW.js → screenshot-command-FYMZF5AF.js} +3 -3
- package/dist-cli/chunks/{screenshot-layers-X65RC3GT.js → screenshot-layers-OXLW6GEJ.js} +2 -2
- package/dist-cli/chunks/{screenshots-capture-BBXN7FEZ.js → screenshots-capture-N3LKTUKB.js} +2 -2
- package/dist-cli/chunks/{serve-M6ZKMSAG.js → serve-USDREK3N.js} +2 -2
- package/dist-cli/chunks/setup-QC7W7NCL.js +4 -0
- package/dist-cli/chunks/{skills-KDWGQBOP.js → skills-3MIZF3DS.js} +2 -2
- package/dist-cli/chunks/{state-NWABXG2P.js → state-MCFLWQHV.js} +2 -2
- package/dist-cli/chunks/{storage-QQE3G65Q.js → storage-KXNS5WEC.js} +2 -2
- package/dist-cli/chunks/store-GL6DFPJL.js +4 -0
- package/dist-cli/chunks/telemetry-OOW5FMZQ.js +4 -0
- package/dist-cli/chunks/{timeline-2VZ45MMB.js → timeline-QJ3USMSX.js} +2 -2
- package/dist-cli/chunks/{upgrade-T7PDR6T5.js → upgrade-LXFD4DFX.js} +2 -2
- package/dist-cli/chunks/upload-EUEO4D5N.js +4 -0
- package/dist-cli/chunks/{version-BX6QX5XA.js → version-D5DLNPHP.js} +2 -2
- package/dist-cli/chunks/{web-4J6JRZN2.js → web-FRFNTTZ4.js} +2 -2
- package/dist-cli/chunks/welcome-YYYGS5WD.js +5 -0
- package/dist-cli/chunks/{what-happened-CHQKFNCM.js → what-happened-FJ6GRQAS.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +2 -2
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +21 -1
- package/dist-lib/host/bridge-host.cjs +1 -1
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +2 -2
- 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 +2 -2
- 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 +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +87 -22
- package/dist-lib/vite.cjs +2 -2
- package/package.json +1 -1
- package/skills/contrast/SKILL.md +3 -3
- package/skills/rnx-setup/SKILL.md +17 -5
- package/src/agent-daemon-client.ts +1 -1
- package/src/home-paths.ts +22 -0
- package/src/metro-plugin.ts +1 -1
- package/src/runtime-assets.ts +1 -1
- package/dist-cli/chunks/chunk-2JZXOHH6.js +0 -4
- package/dist-cli/chunks/chunk-2WJABJ6C.js +0 -15
- package/dist-cli/chunks/chunk-5OVXQKUP.js +0 -25
- package/dist-cli/chunks/chunk-DFTG53TX.js +0 -11
- package/dist-cli/chunks/chunk-HF2FZ2WN.js +0 -7
- package/dist-cli/chunks/chunk-S63ENXGH.js +0 -6
- package/dist-cli/chunks/chunk-UHP33XGC.js +0 -124
- package/dist-cli/chunks/cli-version-6SQSIFNQ.js +0 -4
- package/dist-cli/chunks/control-GLBCTKAA.js +0 -4
- package/dist-cli/chunks/daemon-H4OVIEMH.js +0 -4
- package/dist-cli/chunks/drivers-63LY2NCK.js +0 -4
- package/dist-cli/chunks/flow-JHKPF7BN.js +0 -4
- package/dist-cli/chunks/help-Q6OY6VVA.js +0 -4
- package/dist-cli/chunks/home-paths-UOATIRKF.js +0 -4
- package/dist-cli/chunks/inspect-DW3V2FD4.js +0 -4
- package/dist-cli/chunks/install-desktop-GWY5H22W.js +0 -4
- package/dist-cli/chunks/privacy-34FNXPJP.js +0 -4
- package/dist-cli/chunks/reset-BAGCFYTS.js +0 -4
- package/dist-cli/chunks/runtime-JTYB4CM7.js +0 -4
- package/dist-cli/chunks/setup-KTWKZOJB.js +0 -30
- package/dist-cli/chunks/store-6XW4YZM6.js +0 -4
- package/dist-cli/chunks/telemetry-MVSV7JHI.js +0 -4
- package/dist-cli/chunks/upload-RF2MNO2X.js +0 -4
- package/dist-cli/chunks/welcome-3MJHGERV.js +0 -5
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.353 | (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;
|
|
@@ -10668,6 +10668,7 @@ __export(home_paths_exports, {
|
|
|
10668
10668
|
isDaemonLockfileFresh: () => isDaemonLockfileFresh,
|
|
10669
10669
|
isDevBridgeLockfileFresh: () => isDevBridgeLockfileFresh,
|
|
10670
10670
|
isDevWorkstation: () => isDevWorkstation,
|
|
10671
|
+
isOnboardingComplete: () => isOnboardingComplete,
|
|
10671
10672
|
isSootsimDevCheckout: () => isSootsimDevCheckout,
|
|
10672
10673
|
profilesDir: () => profilesDir,
|
|
10673
10674
|
readActiveRuntime: () => readActiveRuntime,
|
|
@@ -10677,6 +10678,7 @@ __export(home_paths_exports, {
|
|
|
10677
10678
|
readOrCreateAnonymousId: () => readOrCreateAnonymousId,
|
|
10678
10679
|
readPrivacyPreferences: () => readPrivacyPreferences,
|
|
10679
10680
|
readSharedConfig: () => readSharedConfig,
|
|
10681
|
+
readSimulatorDriverPreference: () => readSimulatorDriverPreference,
|
|
10680
10682
|
removeDaemonLockfile: () => removeDaemonLockfile,
|
|
10681
10683
|
removeDevBridgeLockfile: () => removeDevBridgeLockfile,
|
|
10682
10684
|
runtimeDir: () => runtimeDir,
|
|
@@ -10687,6 +10689,7 @@ __export(home_paths_exports, {
|
|
|
10687
10689
|
writeActiveRuntime: () => writeActiveRuntime,
|
|
10688
10690
|
writeDaemonLockfile: () => writeDaemonLockfile,
|
|
10689
10691
|
writeDevBridgeLockfile: () => writeDevBridgeLockfile,
|
|
10692
|
+
writeOnboardingPreferences: () => writeOnboardingPreferences,
|
|
10690
10693
|
writePrivacyPreferences: () => writePrivacyPreferences,
|
|
10691
10694
|
writeRuntimeUpgradeNotice: () => writeRuntimeUpgradeNotice,
|
|
10692
10695
|
writeSharedConfig: () => writeSharedConfig
|
|
@@ -10793,6 +10796,19 @@ function writeSharedConfig(patch) {
|
|
|
10793
10796
|
import_node_fs3.default.renameSync(tmp, configFilePath());
|
|
10794
10797
|
return next;
|
|
10795
10798
|
}
|
|
10799
|
+
function isOnboardingComplete() {
|
|
10800
|
+
return readSharedConfig().onboardingVersion === CURRENT_ONBOARDING_VERSION;
|
|
10801
|
+
}
|
|
10802
|
+
function readSimulatorDriverPreference() {
|
|
10803
|
+
const driver = readSharedConfig().simulatorDriver;
|
|
10804
|
+
return driver === "electron" || driver === "playwright" ? driver : null;
|
|
10805
|
+
}
|
|
10806
|
+
function writeOnboardingPreferences(driver) {
|
|
10807
|
+
writeSharedConfig({
|
|
10808
|
+
onboardingVersion: CURRENT_ONBOARDING_VERSION,
|
|
10809
|
+
simulatorDriver: driver
|
|
10810
|
+
});
|
|
10811
|
+
}
|
|
10796
10812
|
function readPrivacyPreferences() {
|
|
10797
10813
|
const settings = readSharedConfig().settings;
|
|
10798
10814
|
const productAnalytics = settings?.productAnalytics;
|
|
@@ -11138,7 +11154,7 @@ function removeDevBridgeLockfile(owner) {
|
|
|
11138
11154
|
} catch {
|
|
11139
11155
|
}
|
|
11140
11156
|
}
|
|
11141
|
-
var import_node_crypto, import_node_fs3, import_node_os, import_node_path4, SOOTSIM_HOME_ENV, ACTIVE_RUNTIME_FILE, DAEMON_LOCKFILE, DEV_BRIDGES_DIR, CONFIG_FILE, DAEMON_HEARTBEAT_STALE_MS, DAEMON_LOCKFILE_MAX_BYTES, DAEMON_CLAIM_STALE_MS;
|
|
11157
|
+
var import_node_crypto, import_node_fs3, import_node_os, import_node_path4, SOOTSIM_HOME_ENV, ACTIVE_RUNTIME_FILE, DAEMON_LOCKFILE, DEV_BRIDGES_DIR, CONFIG_FILE, DAEMON_HEARTBEAT_STALE_MS, CURRENT_ONBOARDING_VERSION, DAEMON_LOCKFILE_MAX_BYTES, DAEMON_CLAIM_STALE_MS;
|
|
11142
11158
|
var init_home_paths = __esm({
|
|
11143
11159
|
"src/home-paths.ts"() {
|
|
11144
11160
|
"use strict";
|
|
@@ -11152,6 +11168,7 @@ var init_home_paths = __esm({
|
|
|
11152
11168
|
DEV_BRIDGES_DIR = "dev-bridges";
|
|
11153
11169
|
CONFIG_FILE = "config.json";
|
|
11154
11170
|
DAEMON_HEARTBEAT_STALE_MS = 3e4;
|
|
11171
|
+
CURRENT_ONBOARDING_VERSION = 1;
|
|
11155
11172
|
DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
|
|
11156
11173
|
DAEMON_CLAIM_STALE_MS = 3e4;
|
|
11157
11174
|
}
|
|
@@ -18199,9 +18216,9 @@ function findElectronBin(startDir) {
|
|
|
18199
18216
|
function findMacApp() {
|
|
18200
18217
|
const root = getSootsimRoot();
|
|
18201
18218
|
const candidates = [
|
|
18202
|
-
"/Applications/
|
|
18203
|
-
(0, import_path5.resolve)(process.env.HOME || "", "Applications/
|
|
18204
|
-
...root ? [(0, import_path5.resolve)(root, "app/
|
|
18219
|
+
"/Applications/rnx.app",
|
|
18220
|
+
(0, import_path5.resolve)(process.env.HOME || "", "Applications/rnx.app"),
|
|
18221
|
+
...root ? [(0, import_path5.resolve)(root, "app/rnx.app")] : []
|
|
18205
18222
|
];
|
|
18206
18223
|
const found = candidates.find((candidate) => (0, import_fs6.existsSync)(candidate));
|
|
18207
18224
|
if (found) {
|
|
@@ -18230,20 +18247,17 @@ function findMacApp() {
|
|
|
18230
18247
|
}
|
|
18231
18248
|
function findFirstAppImage(dir) {
|
|
18232
18249
|
if (!(0, import_fs6.existsSync)(dir)) return null;
|
|
18233
|
-
const match = (0, import_fs6.readdirSync)(dir).filter((entry) => entry.startsWith("
|
|
18250
|
+
const match = (0, import_fs6.readdirSync)(dir).filter((entry) => entry.startsWith("rnx") && entry.endsWith(".AppImage")).sort().reverse()[0];
|
|
18234
18251
|
return match ? (0, import_path5.join)(dir, match) : null;
|
|
18235
18252
|
}
|
|
18236
18253
|
function findLinuxInstall() {
|
|
18237
18254
|
const root = getSootsimRoot();
|
|
18238
18255
|
const directCandidates = [
|
|
18239
|
-
(0, import_path5.resolve)(process.env.HOME || "", "Applications/
|
|
18240
|
-
(0, import_path5.resolve)(process.env.HOME || "", ".local/bin/
|
|
18241
|
-
"/opt/
|
|
18242
|
-
"/opt/
|
|
18243
|
-
...root ? [
|
|
18244
|
-
(0, import_path5.resolve)(root, "app/sootsim.AppImage"),
|
|
18245
|
-
(0, import_path5.resolve)(root, "release/linux-unpacked/sootsim")
|
|
18246
|
-
] : []
|
|
18256
|
+
(0, import_path5.resolve)(process.env.HOME || "", "Applications/rnx.AppImage"),
|
|
18257
|
+
(0, import_path5.resolve)(process.env.HOME || "", ".local/bin/rnx.AppImage"),
|
|
18258
|
+
"/opt/rnx/rnx.AppImage",
|
|
18259
|
+
"/opt/rnx/rnx",
|
|
18260
|
+
...root ? [(0, import_path5.resolve)(root, "app/rnx.AppImage"), (0, import_path5.resolve)(root, "release/linux-unpacked/rnx")] : []
|
|
18247
18261
|
];
|
|
18248
18262
|
const directMatch = directCandidates.find((candidate) => (0, import_fs6.existsSync)(candidate));
|
|
18249
18263
|
if (directMatch) {
|
|
@@ -18261,6 +18275,23 @@ function findLinuxInstall() {
|
|
|
18261
18275
|
kind: "linux-appimage"
|
|
18262
18276
|
};
|
|
18263
18277
|
}
|
|
18278
|
+
function findWindowsInstall() {
|
|
18279
|
+
for (const hive of ["HKCU", "HKLM"]) {
|
|
18280
|
+
try {
|
|
18281
|
+
const output = (0, import_child_process5.execFileSync)(
|
|
18282
|
+
"reg",
|
|
18283
|
+
["query", `${hive}\\Software\\Classes\\rnx\\shell\\open\\command`, "/ve"],
|
|
18284
|
+
{ encoding: "utf8", timeout: 3e3 }
|
|
18285
|
+
);
|
|
18286
|
+
const executable = /"([^"\r\n]+\.exe)"/i.exec(output)?.[1];
|
|
18287
|
+
if (executable && (0, import_fs6.existsSync)(executable)) {
|
|
18288
|
+
return { path: executable, platform: "win32", kind: "win-exe" };
|
|
18289
|
+
}
|
|
18290
|
+
} catch {
|
|
18291
|
+
}
|
|
18292
|
+
}
|
|
18293
|
+
return null;
|
|
18294
|
+
}
|
|
18264
18295
|
function findDesktopCompanion() {
|
|
18265
18296
|
const dev = findDevElectron();
|
|
18266
18297
|
if (dev) return dev;
|
|
@@ -18282,6 +18313,7 @@ function findDesktopCompanion() {
|
|
|
18282
18313
|
}
|
|
18283
18314
|
if (process.platform === "darwin") return findMacApp();
|
|
18284
18315
|
if (process.platform === "linux") return findLinuxInstall();
|
|
18316
|
+
if (process.platform === "win32") return findWindowsInstall();
|
|
18285
18317
|
return null;
|
|
18286
18318
|
}
|
|
18287
18319
|
async function spawnDetached(command, args, opts = {}) {
|
|
@@ -18328,7 +18360,7 @@ async function launchDesktopCompanion(url, install = findDesktopCompanion(), opt
|
|
|
18328
18360
|
}
|
|
18329
18361
|
function buildMacLaunchUrl(url, opts) {
|
|
18330
18362
|
if (!opts.profileId && !opts.ephemeralProfile && !opts.ownerPid) return url;
|
|
18331
|
-
const deepLink = new URL("
|
|
18363
|
+
const deepLink = new URL("rnx://dev");
|
|
18332
18364
|
deepLink.searchParams.set("url", url);
|
|
18333
18365
|
if (opts.profileId) deepLink.searchParams.set("profile", opts.profileId);
|
|
18334
18366
|
if (opts.ephemeralProfile) deepLink.searchParams.set("ephemeral", "1");
|
|
@@ -19219,6 +19251,32 @@ var init_open_url2 = __esm({
|
|
|
19219
19251
|
}
|
|
19220
19252
|
});
|
|
19221
19253
|
|
|
19254
|
+
// cli/commands/inspect/env.ts
|
|
19255
|
+
function isAgentEnv() {
|
|
19256
|
+
if (process.env.SOOTSIM_AGENT === "0") return false;
|
|
19257
|
+
for (const name2 of AGENT_ENV_VARS) {
|
|
19258
|
+
const v = process.env[name2];
|
|
19259
|
+
if (v && v.trim() && v !== "0") return true;
|
|
19260
|
+
}
|
|
19261
|
+
return false;
|
|
19262
|
+
}
|
|
19263
|
+
var AGENT_ENV_VARS;
|
|
19264
|
+
var init_env = __esm({
|
|
19265
|
+
"cli/commands/inspect/env.ts"() {
|
|
19266
|
+
"use strict";
|
|
19267
|
+
AGENT_ENV_VARS = [
|
|
19268
|
+
"SOOTSIM_AGENT",
|
|
19269
|
+
"TM_SESSION",
|
|
19270
|
+
"CLAUDECODE",
|
|
19271
|
+
"CLAUDE_CODE_ENTRYPOINT",
|
|
19272
|
+
"CLAUDE_CODE_SESSION_ID",
|
|
19273
|
+
"CODEX_THREAD_ID",
|
|
19274
|
+
"CURSOR_TRACE_ID",
|
|
19275
|
+
"AIDER_MODEL"
|
|
19276
|
+
];
|
|
19277
|
+
}
|
|
19278
|
+
});
|
|
19279
|
+
|
|
19222
19280
|
// cli/runtime-notes.ts
|
|
19223
19281
|
function isChangelogEntry(value) {
|
|
19224
19282
|
if (!value || typeof value !== "object") return false;
|
|
@@ -19665,7 +19723,7 @@ async function ensureBridgeForOpen(preferredPort, explicitPort = false) {
|
|
|
19665
19723
|
assertExplicitBridgeLock(preferredPort, explicitPort, nextLock);
|
|
19666
19724
|
if (nextLock && isDaemonLockfileFresh(nextLock) && await canConnectToBridge(nextLock.bridgePort, 250)) {
|
|
19667
19725
|
console.error(
|
|
19668
|
-
`
|
|
19726
|
+
` Started a local bridge on port ${nextLock.bridgePort}. Run \`rnx daemon install\` to keep it ready between commands.`
|
|
19669
19727
|
);
|
|
19670
19728
|
return nextLock.bridgePort;
|
|
19671
19729
|
}
|
|
@@ -20359,7 +20417,7 @@ function resolveTargetSim(sims, requestedId) {
|
|
|
20359
20417
|
if (firstOpen) return firstOpen;
|
|
20360
20418
|
throw new Error("no sim connected");
|
|
20361
20419
|
}
|
|
20362
|
-
function printOpenedSim(openUrl2, sim, mode) {
|
|
20420
|
+
function printOpenedSim(openUrl2, sim, mode, quiet = false) {
|
|
20363
20421
|
const [printableOpenUrl, printableSimUrl] = [openUrl2, sim.url].map((value) => {
|
|
20364
20422
|
if (!value) return value;
|
|
20365
20423
|
try {
|
|
@@ -20372,6 +20430,10 @@ function printOpenedSim(openUrl2, sim, mode) {
|
|
|
20372
20430
|
}
|
|
20373
20431
|
return value;
|
|
20374
20432
|
});
|
|
20433
|
+
if (quiet) {
|
|
20434
|
+
console.log(` Opened ConnectRN [${mode}]`);
|
|
20435
|
+
return;
|
|
20436
|
+
}
|
|
20375
20437
|
console.log(
|
|
20376
20438
|
` ${mode === "current sim" ? "loaded" : "opened"}: ${printableOpenUrl} [${mode}]`
|
|
20377
20439
|
);
|
|
@@ -20526,7 +20588,8 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
20526
20588
|
"--ephemeral",
|
|
20527
20589
|
"--hot",
|
|
20528
20590
|
"--no-hmr",
|
|
20529
|
-
"--no-describe"
|
|
20591
|
+
"--no-describe",
|
|
20592
|
+
"--quiet"
|
|
20530
20593
|
],
|
|
20531
20594
|
stripValueFlags: [
|
|
20532
20595
|
"--base-url",
|
|
@@ -20539,6 +20602,7 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
20539
20602
|
]
|
|
20540
20603
|
});
|
|
20541
20604
|
const requestedProfileId = args.find((_, i) => args[i - 1] === "--profile");
|
|
20605
|
+
const quiet = args.includes("--quiet");
|
|
20542
20606
|
const ephemeralProfile = args.includes("--ephemeral");
|
|
20543
20607
|
const cdpPortArg = args.find((_, i) => args[i - 1] === "--cdp-port");
|
|
20544
20608
|
const cdpPort = cdpPortArg ? Number(cdpPortArg) : void 0;
|
|
@@ -20623,7 +20687,7 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
20623
20687
|
console.error(` unknown driver "${requestedDriverId}" \u2014 run \`rnx list --drivers\``);
|
|
20624
20688
|
process.exit(1);
|
|
20625
20689
|
}
|
|
20626
|
-
const driverId = isDriverId(requestedDriverId) ? requestedDriverId : "playwright";
|
|
20690
|
+
const driverId = isDriverId(requestedDriverId) ? requestedDriverId : process.env.CI === "1" || process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true" || isAgentEnv() || !process.stdin.isTTY ? "playwright" : readSimulatorDriverPreference() || "playwright";
|
|
20627
20691
|
const driverHeadless = resolveDriverHeadless(args, driverId);
|
|
20628
20692
|
if (cdpPort && driverId !== "playwright") {
|
|
20629
20693
|
console.error(" rnx open: --cdp-port is only honored by the playwright driver");
|
|
@@ -20635,7 +20699,7 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
20635
20699
|
console.error(" rnx open: --hot and --no-hmr cannot be combined");
|
|
20636
20700
|
process.exit(1);
|
|
20637
20701
|
}
|
|
20638
|
-
const hotMode = hotFlag ? true : noHmrFlag ? false :
|
|
20702
|
+
const hotMode = hotFlag ? true : noHmrFlag ? false : driverId !== "playwright";
|
|
20639
20703
|
const deviceArg = args.find((_, i) => args[i - 1] === "--device");
|
|
20640
20704
|
if (deviceArg && !(deviceArg in import_settings.devices)) {
|
|
20641
20705
|
console.error(` rnx open: unknown device "${deviceArg}"`);
|
|
@@ -20761,7 +20825,7 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
20761
20825
|
applySootSimConfigToUrl(resolvedBaseUrl, runtimeConfig),
|
|
20762
20826
|
buildShellUrlOpts
|
|
20763
20827
|
);
|
|
20764
|
-
printOpenedSim(shellUrl, { ...targetSim, url: shellUrl }, "current sim");
|
|
20828
|
+
printOpenedSim(shellUrl, { ...targetSim, url: shellUrl }, "current sim", quiet);
|
|
20765
20829
|
await maybeDescribeAfterOpen(parsed.wsPort, targetSim.id, args);
|
|
20766
20830
|
return parsed.wsPort;
|
|
20767
20831
|
}
|
|
@@ -20834,7 +20898,7 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
20834
20898
|
const match = outcome.sim;
|
|
20835
20899
|
saveCurrentSimId(match.id);
|
|
20836
20900
|
signalDriverLaunchConnected(result);
|
|
20837
|
-
printOpenedSim(openUrl2, match, `${driver.name} driver
|
|
20901
|
+
printOpenedSim(openUrl2, match, `${driver.name} driver`, quiet);
|
|
20838
20902
|
await maybeDescribeAfterOpen(parsed.wsPort, match.id, args);
|
|
20839
20903
|
return parsed.wsPort;
|
|
20840
20904
|
}
|
|
@@ -21130,6 +21194,7 @@ var init_control = __esm({
|
|
|
21130
21194
|
init_open_url2();
|
|
21131
21195
|
init_ws_bridge();
|
|
21132
21196
|
init_core();
|
|
21197
|
+
init_env();
|
|
21133
21198
|
DEFAULT_DRIVER_CONNECT_TIMEOUT_MS = 12e4;
|
|
21134
21199
|
DRIVER_CONNECT_INTERVAL_MS = 100;
|
|
21135
21200
|
DRIVER_CONNECT_HOST_GRACE_MS = 5e3;
|
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.353 | (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;
|
|
@@ -446,7 +446,7 @@ function isValidRuntimeVersion(value) {
|
|
|
446
446
|
}
|
|
447
447
|
|
|
448
448
|
// src/runtime-assets.ts
|
|
449
|
-
var SOOTSIM_RUNTIME_MISSING_MESSAGE = "[rnx] no engine runtime installed
|
|
449
|
+
var SOOTSIM_RUNTIME_MISSING_MESSAGE = "[rnx] no engine runtime installed. run `rnx runtime install`";
|
|
450
450
|
var _monorepoRootCache;
|
|
451
451
|
function findMonorepoRoot() {
|
|
452
452
|
if (_monorepoRootCache !== void 0) return _monorepoRootCache;
|
package/package.json
CHANGED
package/skills/contrast/SKILL.md
CHANGED
|
@@ -49,11 +49,11 @@ automation, inspecting the render tree, and managing sims.
|
|
|
49
49
|
| `rnx claim` | take an exclusive lease on a sim |
|
|
50
50
|
| `rnx agent` | attached projects + local agent sessions (codex/claude) |
|
|
51
51
|
| `rnx close` | close a connected sim |
|
|
52
|
-
| `rnx setup` |
|
|
52
|
+
| `rnx setup` | configure optional local conveniences |
|
|
53
53
|
| `rnx compat` | check package compatibility |
|
|
54
54
|
| `rnx report-issue` | send an explicitly approved compatibility report |
|
|
55
55
|
| `rnx desktop` | launch or install the desktop companion |
|
|
56
|
-
| `rnx daemon` | manage the
|
|
56
|
+
| `rnx daemon` | manage the recommended background bridge service |
|
|
57
57
|
| `rnx version` | show the CLI + engine runtime versions you are running |
|
|
58
58
|
| `rnx upgrade` | update the rnx CLI and engine runtime to the latest |
|
|
59
59
|
| `rnx serve` | run the rnx bridge in the foreground |
|
|
@@ -92,7 +92,7 @@ skills for working with the rnx native preview engine:
|
|
|
92
92
|
| --- | --- |
|
|
93
93
|
| `/rnx-debug` | Debug rendering, animation, gesture, performance, and accessibility issues in a React Native app running under rnx. Reach for this whenever an animation looks wrong (janky, stutters, snaps, only updates once, or doesn't move at all), a swipe/transition/gesture misbehaves or feels broken, scrolling drops frames or feels slow, the UI renders the wrong tree/props, or a screen reader can't reach something — and drive the rnx CLI debug tooling first, not screenshots or ad-hoc logging. |
|
|
94
94
|
| `/rnx-perf` | Optimize rnx engine and app performance — scroll jank, dropped frames, slow animation, idle CPU, memory growth, and "smooth normally but laggy under load" (video calls, busy machines). Covers measuring on the right thread with the right browser, proving each perf tier actually engages via its counters, a CPU-contention test harness, and the map of existing perf machinery so you improve it instead of reinventing it. For general app debugging load /rnx-debug first. |
|
|
95
|
-
| `/rnx-setup` | Get rnx connected to your React Native app
|
|
95
|
+
| `/rnx-setup` | Get rnx connected to your React Native app with no project setup |
|
|
96
96
|
| `/rnx-test` | Run automated tests against your React Native app under rnx with Maestro YAML or Detox/Jest |
|
|
97
97
|
| `/rnx-visual` | Pixel-level rendering comparison between rnx and native iOS — fonts, gradients, shadows, image fidelity |
|
|
98
98
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rnx-setup
|
|
3
|
-
description: Get rnx connected to your React Native app
|
|
3
|
+
description: Get rnx connected to your React Native app with no project setup
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# rnx setup
|
|
7
7
|
|
|
8
8
|
you want to drive a React Native app with rnx from the CLI. this skill
|
|
9
|
-
takes you from
|
|
10
|
-
rnx skill assumes exists.
|
|
9
|
+
takes you from a running development server to a connected, pinned sim that
|
|
10
|
+
every other rnx skill assumes exists. rnx requires no project setup or per-app
|
|
11
|
+
install. if
|
|
11
12
|
`rnx describe` already
|
|
12
13
|
returns a tree, you're past this skill — load `/rnx-debug` for
|
|
13
14
|
debugging or `/rnx-test` for writing tests.
|
|
@@ -58,7 +59,8 @@ debugging or `/rnx-test` for writing tests.
|
|
|
58
59
|
## first move
|
|
59
60
|
|
|
60
61
|
```sh
|
|
61
|
-
rnx
|
|
62
|
+
rnx daemon status # the persistent service makes agent commands much faster
|
|
63
|
+
rnx daemon install # enable it when missing on a supported personal machine
|
|
62
64
|
rnx compat --json # scan the app's native package compatibility
|
|
63
65
|
rnx open 8081 # load a metro/expo dev server
|
|
64
66
|
rnx list # confirm exactly one sim is reachable
|
|
@@ -66,6 +68,15 @@ rnx use <id> # pin it for the rest of the workflow
|
|
|
66
68
|
rnx describe # smoke test — should print a render tree
|
|
67
69
|
```
|
|
68
70
|
|
|
71
|
+
the background service keeps the local bridge and runtime ready between
|
|
72
|
+
commands. without it, rnx still works by starting an on-demand bridge, but
|
|
73
|
+
inspect, interaction, and test commands pay repeated startup cost. if the user
|
|
74
|
+
declined it during onboarding, `rnx daemon install` is the direct way to enable
|
|
75
|
+
it. CI does not need or install the service.
|
|
76
|
+
|
|
77
|
+
bare `rnx` opens ConnectRN for a human to choose among local apps. agents and
|
|
78
|
+
scripts should use `rnx open <port-or-url>` so the target is explicit.
|
|
79
|
+
|
|
69
80
|
if you do not know the port, run `rnx open` with no target and pick from
|
|
70
81
|
the detected dev servers. for hosted or unusual targets, pass the URL
|
|
71
82
|
explicitly:
|
|
@@ -118,7 +129,8 @@ rnx runtime list # is at least one engine runtime installed?
|
|
|
118
129
|
rnx open <port> # does loading explicitly work?
|
|
119
130
|
```
|
|
120
131
|
|
|
121
|
-
if daemon is
|
|
132
|
+
if the daemon is not installed: run `rnx daemon install`. if the registered
|
|
133
|
+
daemon is down, run `rnx daemon restart`, or `rnx serve` in another shell for
|
|
122
134
|
a foreground bridge. if no runtime is installed, `rnx open` installs it
|
|
123
135
|
before launching. if open errors with "port unreachable": confirm your dev
|
|
124
136
|
server is actually serving — the bundler has to be up before rnx can
|
|
@@ -361,7 +361,7 @@ export async function ensureDaemonRunning(
|
|
|
361
361
|
}
|
|
362
362
|
if (shouldSkipPersistentDaemon()) {
|
|
363
363
|
throw new AgentDaemonError(
|
|
364
|
-
`no rnx bridge on port ${port}. run \`rnx
|
|
364
|
+
`no rnx bridge on port ${port}. run \`rnx daemon install\` to enable the faster background service, or \`rnx serve\` in another shell.`,
|
|
365
365
|
'DEV_HOST_REFUSED',
|
|
366
366
|
)
|
|
367
367
|
}
|
package/src/home-paths.ts
CHANGED
|
@@ -187,6 +187,8 @@ export function configFilePath(): string {
|
|
|
187
187
|
|
|
188
188
|
export interface SharedConfig {
|
|
189
189
|
telemetry?: boolean
|
|
190
|
+
onboardingVersion?: number
|
|
191
|
+
simulatorDriver?: 'electron' | 'playwright'
|
|
190
192
|
settings?: Record<string, unknown>
|
|
191
193
|
[key: string]: unknown
|
|
192
194
|
}
|
|
@@ -222,6 +224,26 @@ export function writeSharedConfig(patch: Partial<SharedConfig>): SharedConfig {
|
|
|
222
224
|
return next
|
|
223
225
|
}
|
|
224
226
|
|
|
227
|
+
const CURRENT_ONBOARDING_VERSION = 1
|
|
228
|
+
|
|
229
|
+
export type SimulatorDriverPreference = 'electron' | 'playwright'
|
|
230
|
+
|
|
231
|
+
export function isOnboardingComplete(): boolean {
|
|
232
|
+
return readSharedConfig().onboardingVersion === CURRENT_ONBOARDING_VERSION
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function readSimulatorDriverPreference(): SimulatorDriverPreference | null {
|
|
236
|
+
const driver = readSharedConfig().simulatorDriver
|
|
237
|
+
return driver === 'electron' || driver === 'playwright' ? driver : null
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export function writeOnboardingPreferences(driver: SimulatorDriverPreference): void {
|
|
241
|
+
writeSharedConfig({
|
|
242
|
+
onboardingVersion: CURRENT_ONBOARDING_VERSION,
|
|
243
|
+
simulatorDriver: driver,
|
|
244
|
+
})
|
|
245
|
+
}
|
|
246
|
+
|
|
225
247
|
export interface PrivacyPreferences {
|
|
226
248
|
productAnalytics: boolean
|
|
227
249
|
crashReports: boolean
|
package/src/metro-plugin.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// rnx metro plugin for opt-in dev shell and production bundle integration.
|
|
2
2
|
// shell assets come from an engine runtime under ~/.sootsim/runtimes/, fetched
|
|
3
|
-
// by `
|
|
3
|
+
// by `rnx runtime install`. ordinary localhost requests
|
|
4
4
|
// follow active; a version-owned localhost origin stays on its exact directory
|
|
5
5
|
// when active changes, so one loaded shell cannot mix runtime chunk trees.
|
|
6
6
|
//
|
package/src/runtime-assets.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { isValidRuntimeVersion } from '@contrast/runtime-delivery'
|
|
|
9
9
|
import { readActiveRuntime, runtimeDir } from './home-paths.ts'
|
|
10
10
|
|
|
11
11
|
export const SOOTSIM_RUNTIME_MISSING_MESSAGE =
|
|
12
|
-
'[rnx] no engine runtime installed
|
|
12
|
+
'[rnx] no engine runtime installed. run `rnx runtime install`'
|
|
13
13
|
|
|
14
14
|
// --- dev-checkout mode boundary --------------------------------------------
|
|
15
15
|
//
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
/*! rnx v0.1.352 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
|
-
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
function p(){console.error(" no rnx desktop companion found."),console.error(""),console.error(" install the desktop app:"),console.error(" rnx desktop install"),console.error(""),console.error(" or run setup to install the background daemon:"),console.error(" rnx setup"),console.error("")}function t(r){console.error(""),console.error(` no sim is connected to the rnx bridge on port ${r}.`),console.error(""),console.error(" start your app dev server, then open it in rnx:"),console.error(" npx expo start --localhost --port 8081"),console.error(" rnx open 8081"),console.error(""),console.error(" then inspect the live app:"),console.error(" rnx describe")}async function a(r,n,s){let e=[];try{e=await r.listSims()}catch{}if(console.error(""),e.length===0){t(n);return}console.error(` no sim with id "${s}" is connected to the bridge on port ${n}.`),console.error(""),console.error(" connected sims:");for(let o of e){let i=[o.isPrimary?"primary":null,o.readyState,o.userVisible===!1?"hidden":o.userVisible===!0?"visible":null,o.userFocused?"focused":null].filter(Boolean).join(", ");console.error(` ${o.id} (${i})`)}console.error(""),console.error(" pass a valid --sim id, or run `rnx list` to see all sessions.")}export{p as a,t as b,a as c};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/*! rnx v0.1.352 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
|
-
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
import{a as ue,b as Fe}from"./chunk-6NSUY346.js";import{a as qe,b as ze,d as Ye}from"./chunk-DSF4WC4X.js";import{a as Me,b as Be,c as I,d as le,e as L,f as ce,g as De,h as de,i as Le,j as Ae,l as We,m as Ke,n as Ve}from"./chunk-4AOAJXE2.js";import{b as ie,d as Re}from"./chunk-RH6FJI5O.js";import{a as He}from"./chunk-RASWCAJJ.js";import{a as je}from"./chunk-ELNSQ352.js";import{m as A}from"./chunk-TF6VBUZ7.js";import{m as Ge,p as Je}from"./chunk-H4IF54WS.js";import{b as Ue,f as Ee,g as B,h as $,i as D,k as _e,l as se,m as ae,o as Oe,p as Te,q as E,r as P,s as _}from"./chunk-EHQHK7KN.js";import{e as Qe}from"./chunk-ESVF72YH.js";import{c as Ne}from"./chunk-3Y7NWE22.js";import{f as Ce}from"./chunk-M6DC6JZL.js";import{J as re,M as oe,O as M,Q as ke,l as ne}from"./chunk-DFTG53TX.js";import{a as te}from"./chunk-BQE4E24T.js";import{spawn as rt,spawnSync as ot}from"node:child_process";import O from"node:fs";import Tt from"node:os";import C from"node:path";import{WebSocket as me}from"ws";function Ze(e){return new Error(`could not resolve a native bundle for ${e}. pass an explicit bundle URL or open Connect and choose the app there.`)}function kt(e,n){return e?.includes("/one/metro-entry.bundle")?"one":typeof n=="string"&&n?"expo":"unknown"}function Ct(e,n,t){return`${e}//${n}:${t}`}function Rt(e){if(typeof window>"u")return!1;try{let n=new URL(e);return I(n.hostname)&&I(window.location.hostname)&&n.origin!==window.location.origin}catch{return!1}}async function Xe(e,n){let t={...n,cache:n?.cache??"no-store"};return Rt(e)?fetch(`/__fetch-proxy?url=${encodeURIComponent(e)}`,t):fetch(e,t)}function Ut(e){return e==="https:"?443:80}function Et(e){let n=e.pathname||"/";return(n==="/"||n==="")&&!e.search&&!e.hash}async function et(e){try{let n=await fetch("/__server-scan",{cache:"no-store"});if(!n.ok||!(n.headers.get("content-type")||"").toLowerCase().includes("json"))return null;let t=await n.json();if(!Array.isArray(t))return null;let r=t.find(o=>!!o&&typeof o=="object"&&o.port===e&&typeof o.bundleUrl=="string");return r?{bundleUrl:de(r.bundleUrl),port:e,framework:typeof r.framework=="string"?r.framework:"unknown",projectName:typeof r.projectName=="string"?r.projectName:void 0}:null}catch{return null}}async function tt(e,n){let t=e.replace(/\/+$/,"");try{let r=await Xe(`${t}/`,{headers:{"expo-platform":"ios"}});if(r.ok){let o=await r.json(),i=o?.extra?.expoClient||o?.extra||{},s=typeof o?.launchAsset?.url=="string"?o.launchAsset.url:void 0,a=s?De(s,t):void 0;if(a||i.name)return{bundleUrl:de(a||`${t}${ce}`),port:n,framework:kt(a,i.sdkVersion),projectName:i.name}}}catch{}try{let r=await Xe(`${t}/status`);if(r.ok&&(await r.text()).includes("packager-status:running"))return{bundleUrl:`${t}${ce}`,port:n,framework:"metro"}}catch{}return null}async function _t(e,n){try{if(I(new URL(e).hostname)){let t=await et(n);if(t)return t}}catch{}return tt(e,n)}async function Ot(e){let n=await et(e);return n||((await Promise.all(Me.map(r=>tt(Be("http:",r,e),e)))).find(r=>r!==null)??null)}async function nt(e){let n=e.trim();if(/^\d+$/.test(n)){let a=parseInt(n,10),l=await Ot(a);if(l)return l;throw Ze(`localhost:${a}`)}let t=n.startsWith("http")?n:`http://${n}`,r;try{r=new URL(t)}catch{throw new Error(`could not parse "${e}". pass a dev-server port, a dev-server base URL, or a full bundle URL.`)}let o=r.protocol||"http:",i=r.port?parseInt(r.port,10):Ut(o),s=Ct(o,r.hostname,i);if(Et(r)){let a=await _t(s,i);if(a)return a;throw Ze(s)}return{bundleUrl:r.toString(),port:i,framework:"unknown"}}var Mt=12e4,it=100,Bt=5e3,st=1e4,Dt={rn:"/rn",connectrn:"/rn","connect-rn":"/rn",clock:"/app/clock","native-ui":"/app/native-ui",tamagui:"/app/tamagui",settings:"/app/settings",photos:"/app/photos",camera:"/app/camera"};function y(e){return new Promise(n=>setTimeout(n,e))}function at(e){let n=process.env[e]?.trim();if(!n)return null;let t=Number(n);return Number.isInteger(t)&&t>0?t:null}function Lt(){let e=at("SOOTSIM_DRIVER_CONNECT_TIMEOUT_MS")??at("SOOTSIM_PW_CONNECT_TIMEOUT_MS")??Mt;return{timeoutMs:e,hostTimeoutMs:e+Bt,intervalMs:it,attempts:Math.max(1,Math.ceil(e/it))}}function lt(e){return e==="electron"||e==="playwright"}function pe(e,n){return n==="playwright"?e.meta?.sootsimHostDriver==="playwright":e.userAgent?.includes("Electron/")===!0}function At(e,n){return e.includes("--headless")?!0:e.includes("--headed")?!1:n==="playwright"&&process.platform==="linux"&&!process.env.DISPLAY&&!process.env.WAYLAND_DISPLAY?(console.error(" no display detected \u2192 running playwright headless (override with --headed)"),!0):!1}function z(e){return e.trim()}var gt=/^[A-Za-z][A-Za-z0-9+.-]*:/;function Nt(e){let n=e.trim();if(!n)throw new Error("expected <url-or-route>");return gt.test(n)||n.startsWith("/")?n:`/${n}`}function Ft(e){return e!==null&&typeof e=="object"}function jt(e){let n=e.trim();return n?n.startsWith("/")?!0:gt.test(n)?!/^https?:\/\//i.test(n):!1:!1}async function Ht(e,n=!1){let t=oe();ct(e,n,t);let r=se(e);if((n||r!==null)&&await fe(e,250))return e;if(t&&M(t)&&await fe(t.bridgePort,500))return t.bridgePort;if(t&&M(t))throw new Error(`rnx bridge lockfile is fresh (port ${t.bridgePort}) but the bridge is not reachable. run \`rnx daemon restart\` or \`rnx daemon uninstall\`.`);await Wt();let o=Kt(["serve","--quiet","--port",String(e)]),i=null;o.once("exit",(a,l)=>{i=String(a??l??"unknown")}),o.unref();let s=Date.now()+st;for(;Date.now()<s;){let a=oe();if(ct(e,n,a),a&&M(a)&&await fe(a.bridgePort,250))return console.error(` started local bridge on port ${a.bridgePort}; run \`sootsim setup\` to install the background daemon`),a.bridgePort;if(i)throw new Error(`rnx bridge exited before becoming ready (exit ${i})`);await y(150)}throw new Error(`rnx bridge did not start within ${Math.round(st/1e3)}s`)}function ct(e,n,t){if(!(!n||!t||!M(t)||t.bridgePort===e))throw new Error(`${te.commandName} open: requested bridge port ${e}, but the active daemon owns port ${t.bridgePort}. explicit --port never selects another bridge; stop that daemon or use an isolated SOOTSIM_HOME.`)}async function Wt(){let e=re();if(e&&O.existsSync(ne(e)))return;console.error(" installing rnx engine runtime...");let{runRuntime:n}=await import("./runtime-JTYB4CM7.js");await n(["install"],{})}function Kt(e){let n=process.argv[1];return n&&O.existsSync(n)?rt(process.execPath,[n,...e],{detached:!0,stdio:"ignore",env:process.env}):rt(te.commandName,e,{detached:!0,stdio:"ignore",env:process.env})}function fe(e,n){return new Promise(t=>{let r=new me(`ws://127.0.0.1:${e}`,{handshakeTimeout:n}),o=!1,i=s=>{o||(o=!0,r.readyState===me.OPEN?r.close():r.readyState===me.CONNECTING&&r.terminate(),t(s))};r.once("open",()=>i(!0)),r.on("error",()=>i(!1)),setTimeout(()=>i(!1),n)})}function he(e){try{let n=new URL(e),t=n.pathname.replace(/\/+$/,"")||"/";return n.searchParams.has("open")||n.searchParams.has("port")||n.searchParams.has("bundle")||n.searchParams.has("demo")||n.pathname.includes("/sootsim/index.html")||t==="/sootsim"||n.pathname==="/__soot"||n.pathname==="/__soot/"||t==="/rn"||/^\/rn\/[^/]+$/i.test(t)||/^\/app\/[^/]+$/i.test(t)||t==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(t)||/^\/__soot\/app\/[^/]+$/i.test(t)}catch{return!1}}function Vt(e){try{let n=new URL(e,"http://sootsim.local");if(n.origin!=="http://sootsim.local")return!1;let t=n.pathname.replace(/\/+$/,"")||"/";return t==="/rn"||/^\/rn\/[^/]+$/i.test(t)||/^\/app\/[^/]+$/i.test(t)||t==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(t)||/^\/__soot\/app\/[^/]+$/i.test(t)}catch{return!1}}function qt(e,n){let t=new URL(e,"http://sootsim.local"),r=new URL(n),o=G(r.pathname),i=t.pathname.startsWith("/__soot/")?t.pathname.slice(7):t.pathname;return r.pathname=`${o}${i}`,r.search=t.search,r.hash=t.hash,r.toString()}function zt(e){try{let n=new URL(e).pathname.replace(/\/+$/,"")||"/";return/^\/preview\/[^/]+$/.test(n)||/^\/build\/.+/.test(n)}catch{return!1}}async function tr(e){let n=z(e);return(await be(n)).bundleUrl}function Gt(e){try{let n=new URL(e.startsWith("http")?e:`http://${e}`),t=n.pathname||"/";if(t!=="/"&&t!==""||n.search||n.hash||!I(n.hostname))return null;let r=n.port?Number(n.port):n.protocol==="https:"?443:80;return Number.isFinite(r)&&r>0?r:null}catch{return null}}async function be(e){let n=z(e),t=/^\d+$/.test(n)?Number(n):Gt(n);if(t&&t>0){let r=await Ae(t);if(r)return{bundleUrl:r.bundleUrl,port:r.port,framework:r.framework,projectName:r.projectName}}return nt(n)}function G(e){let n=e.replace(/\/+$/,"")||"/";return n==="/__soot"||n.startsWith("/__soot/")?"/__soot":""}function Jt(e,n){let t=z(e),r=new URL(n),o=G(r.pathname);return r.pathname=`${o}/rn`,r.searchParams.delete("bundle"),r.searchParams.delete("demo"),r.searchParams.delete("app"),r.searchParams.delete("open"),r.searchParams.delete("port"),/^\d+$/.test(t)?r.pathname=`${o}/rn/${t}`:(r.pathname=`${o}/rn`,r.searchParams.set("open",t)),r.toString()}function ht(e){let n=z(e);return/^\d+$/.test(n)||/^https?:\/\//i.test(n)?!0:/^(localhost|127\.0\.0\.1|\[::1\]|[^/]+\.localhost):\d+(?:\/.*)?$/i.test(n)}async function Qt(e,n,t={}){let r=t.resolvedBundle??await be(e),o=new URL(n),i=G(o.pathname);o.pathname=`${i}/rn`,o.searchParams.delete("open"),o.searchParams.delete("port"),o.searchParams.delete("demo"),o.searchParams.delete("app");let s=t.hot===void 0?r.bundleUrl:Le(r.bundleUrl,t.hot);return o.searchParams.set("bundle",s),o.toString()}function Yt(e){return e.startsWith("~/")?C.join(Tt.homedir(),e.slice(2)):C.isAbsolute(e)?e:C.resolve(process.cwd(),e)}function Zt(e){let n={},t={};for(let o=0;o<e.length;o++){if(e[o]==="--replace"){let i=e[o+1];i||(console.error(" rnx open: --replace expects <module>=<file>"),process.exit(1));let s=i.indexOf("=");(s<=0||s===i.length-1)&&(console.error(" rnx open: --replace expects <module>=<file>"),process.exit(1));let a=i.slice(0,s).trim(),l=Yt(i.slice(s+1).trim());O.existsSync(l)||(console.error(` rnx open: replacement file not found: ${l}`),process.exit(1)),n[a]={file:l},o++;continue}if(e[o]==="--remap"){let i=e[o+1],s=i?i.indexOf("="):-1;(!i||s<=0||s===i.length-1)&&(console.error(" rnx open: --remap expects <host:port>=<host:port>"),process.exit(1)),t[i.slice(0,s).trim()]=i.slice(s+1).trim(),o++;continue}}let r={};return Object.keys(n).length>0&&(r.modules=n),Object.keys(t).length>0&&(r.network={remap:t}),r.modules||r.network?r:void 0}async function Xt(e){if(!e)return null;let n=await Ke(e.bundleUrl);return n?je(n):null}async function en(e){if(O.existsSync(C.join(ne(e),"index.html")))return;console.error(` installing configured engine runtime ${e}...`);let n=await Ce.install({version:e,setActive:!1,protectVersions:ke()});console.error(` installed engine runtime ${n.version}`)}function tn(e,n){let t=n??(ue()?void 0:re()??void 0);if(!t)return e;let r=new URL(e);if(!I(r.hostname)){if(!n)return e;throw new Error(`runtimeVersion ${t} requires a local rnx host; got ${r.origin}`)}return r.hostname=Fe(t),r.toString()}function wt(){return _e().shellBaseUrl}function nn(e){return se(e)?.shellBaseUrl??Ue(e)??wt()}async function rn(e,n){try{let t=new URL(e),r=t.searchParams.get("bundle")||"";if(!r||!n)return e;let o=We({bundleUrl:r,projectDir:n.appDir});if(o.length===0)return e;let i=await on(o);return i.length===0?e:(t.searchParams.set("appFonts",Ve(i)),t.toString())}catch{return e}}async function on(e){let n=await Promise.all(e.map(async r=>{let o=new AbortController,i=setTimeout(()=>o.abort(),1500);try{let s=await fetch(r.url,{method:"HEAD",signal:o.signal});return s.status>=200&&s.status<400?r:null}catch{return null}finally{clearTimeout(i)}})),t=[];for(let r of n)r!==null&&t.push(r);return t}async function sn(e,n,t={}){if(!e)return new URL(n).toString();if(he(e))return new URL(e).toString();if(Vt(e))return qt(e,n);let r=Dt[e.toLowerCase()];if(r){let o=new URL(n),i=G(o.pathname);return o.pathname=`${i}${r}`,o.toString()}return ht(e)?Qt(e,n,t):Jt(e,n)}async function an(e,n){try{let t=new URL(e),r=t.searchParams.get("bundle")||"";if(!r||!n)return e;let o=qe({bundleUrl:r,projectDir:n.appDir});return!o||o.imageUrl&&!await ln(o.imageUrl)?e:(t.searchParams.set("appSplash",ze(o)),t.toString())}catch{return e}}async function ln(e){let n=new AbortController,t=setTimeout(()=>n.abort(),1500);try{let r=await fetch(e,{method:"HEAD",signal:n.signal});return r.status>=200&&r.status<400}catch{return!1}finally{clearTimeout(t)}}async function q(e,n=wt(),t={}){let r=await sn(e,n,t),o=await an(await rn(r,t.project),t.project);if(!t.device)return o;let i=new URL(o);return i.searchParams.set("device",t.device),i.toString()}function dt(e,n){let t=e?.url||e?.origin||n;try{let r=new URL(t);return r.searchParams.delete("bundle"),r.searchParams.delete("demo"),r.searchParams.delete("app"),r.searchParams.delete("open"),r.searchParams.delete("port"),r.searchParams.delete("inspectOpen"),r.searchParams.delete("appFonts"),r.searchParams.delete("appSplash"),r.toString()}catch{return n}}async function cn(e,n,t,r={}){let o=new URL(await q(e,n,r));return o.searchParams.set("inspectOpen",t),o.toString()}async function dn(e,n,t,r={}){let o=r.attempts??30,i=r.intervalMs??500,s=r.minNodeCount??10;for(let a=0;a<o;a++){let l=P(e,{commandTimeoutMs:n,simId:t,simIdSource:"flag"});try{let d=await l.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount()) || 0)()"});if(typeof d=="number"&&d>s)return{bridge:l,count:d}}catch{}l.close(),await y(i)}return null}function un(e){if(!e)return null;try{let n=new URL(e);if(n.searchParams.has("bundle")){let t=n.searchParams.get("bundle")||"";try{let r=new URL(t),o=r.pathname.length>36?`...${r.pathname.slice(-36)}`:r.pathname;return`bundle ${r.host}${o}`}catch{return"bundle"}}return n.searchParams.has("port")?`connect :${n.searchParams.get("port")||""}`:n.searchParams.has("open")?`connect ${n.searchParams.get("open")||""}`:n.searchParams.has("demo")?`demo ${n.searchParams.get("demo")||"default"}`:n.pathname.includes("/sootsim/index.html")||n.pathname==="/sootsim/"||n.pathname==="/sootsim"?"embedded rnx":null}catch{return null}}function mn(e){let n=e.indexOf(":");if(n<=0)return e.length>24?`${e.slice(0,21)}\u2026`:e;let t=e.slice(0,n),r=e.slice(n+1),o=r.length>12?`${r.slice(0,8)}\u2026`:r;return t==="TM_SESSION"||t==="CLAUDE_CODE_SESSION_ID"||t==="CODEX_THREAD_ID"?`agent ${o}`:`${t} ${o}`}function nr(e,n){if(e.length===0){console.log(" no sims connected");return}console.log(` connected sims (${e.length}):
|
|
5
|
-
`);for(let t of e){let r=t.lockedBy&&t.lockExpiresAt?`locked by ${mn(t.lockedBy)} (${Math.max(0,Math.round((t.lockExpiresAt-Date.now())/1e3))}s)`:"",o=[t.isPrimary?"primary":"",t.id===n?"selected":"",t.readyState,t.userVisible===!1?"hidden":t.userVisible===!0?"visible":"",t.attachedCliCount&&t.attachedCliCount>0?"in use":"",t.userFocused?"focused":"",r].filter(Boolean);console.log(` ${t.id}${o.length?` [${o.join(", ")}]`:""}`);let i=un(t.url);if(i)console.log(` loaded: ${i}`);else if(t.url){let a=t.url.length>96?`${t.url.slice(0,93)}\u2026`:t.url;console.log(` url: ${a}`)}else t.origin&&console.log(` origin: ${t.origin}`);let s=pn(t);s&&console.log(` engine: ${s}`),t.title&&console.log(` title: ${t.title}`),t.visibilityState&&t.visibilityState!=="visible"&&console.log(` visibility: ${t.visibilityState}`),console.log(` connected: ${ut(Date.now()-t.connectedAt)}`),t.lastActiveAt&&t.lastActiveAt>0&&console.log(` last active: ${ut(Date.now()-t.lastActiveAt)}`)}}function pn(e){let n=e.url||e.origin||"";if(!n)return null;try{let t=new URL(n).port;return t==="5173"?"dev \u2014 local source (:5173)":t==="3000"?"Contrast app embedded (:3000)":ue()?`dev \u2014 local build (:${t||"?"})`:`runtime \u2014 published engine (:${t||"?"})`}catch{return null}}function ut(e){let n=Math.max(0,Math.round(e/1e3));return n<60?`${n}s ago`:n<3600?`${Math.round(n/60)}m ago`:n<86400?`${Math.round(n/3600)}h ago`:`${Math.round(n/86400)}d ago`}async function rr(e,n,t,r={}){let o=r.attempts??30,i=r.intervalMs??500;for(let s=0;s<o;s++){let a=P(e,{commandTimeoutMs:n});try{let d=(await a.listSims()).find(t);if(d)return d}catch{}finally{a.close()}await y(i)}return null}async function fn(e,n,t,r,o={}){let i=o.attempts??30,s=o.intervalMs??500,a=!!r&&Number.isInteger(r)&&r>1,l=()=>a&&r!==void 0&&!we(r);for(let d=0;d<i;d++){if(l())return{kind:"host-exit"};let c=P(e,{commandTimeoutMs:n});try{let g=(await c.listSims()).find(t);if(g)return l()?{kind:"host-exit"}:{kind:"match",sim:g}}catch{}finally{c.close()}if(l())return{kind:"host-exit"};await y(s)}return{kind:"timeout"}}async function gn(e,n,t,r={}){let o=r.attempts??20,i=r.intervalMs??250;for(let s=0;s<o;s++){let a=P(e,{commandTimeoutMs:n});try{let d=(await a.listSims()).find(c=>c.id===t);if(!d||d.readyState!=="open")return!0}catch{return!0}finally{a.close()}await y(i)}return!1}function hn(e){let n=e.meta;if(!n||n.sootsimHostDriver!=="playwright")return null;let t=Number(n.sootsimHostPid);return!Number.isInteger(t)||t<=1||t===process.pid?null:t}function wn(e){if(!e.connectAckFile)return!1;try{return O.writeFileSync(e.connectAckFile,`${JSON.stringify({connectedAt:Date.now(),pid:e.pid??null})}
|
|
6
|
-
`,{flag:"w"}),!0}catch{return!1}}function mt(e){if(e.diagnosticLogPath)try{let n=O.readFileSync(e.diagnosticLogPath,"utf8").trim();if(!n){console.error(` ${C.basename(e.diagnosticLogPath)} was empty`);return}let t=n.length>4e3?`\u2026
|
|
7
|
-
${n.slice(-4e3)}`:n;console.error(` ${C.basename(e.diagnosticLogPath)}:`),console.error(t)}catch(n){let t=n instanceof Error?n.message:String(n);console.error(` failed to read ${C.basename(e.diagnosticLogPath)}: ${t}`)}}function we(e){try{return process.kill(e,0),!0}catch(n){return n?.code==="EPERM"}}async function bn(e,n=2500){let t=Date.now()+n;for(;Date.now()<t;){if(!we(e))return!0;await y(100)}return!we(e)}function vn(e){let n=ot("ps",["-o","command=","-p",String(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),t=ot("ps",["eww","-o","command=","-p",String(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(n.status!==0||t.status!==0)return!1;let r=(n.stdout||"").trimEnd(),o=(t.stdout||"").trimEnd();return(o.startsWith(r)?o.slice(r.length):o).includes("SOOTSIM_PW_URL=")}async function ge(e,n){let t=new Set(n),r=new Set;for(let o of e){if(!t.has(o.id))continue;let i=hn(o);i&&r.add(i)}for(let o of r){if(!vn(o)){console.log(` skipped pid ${o}: not a rnx playwright host (stale sim record)`);continue}try{process.kill(o,"SIGTERM")}catch{}if(await bn(o)){console.log(` closed playwright host process ${o}`);continue}try{process.kill(o,"SIGKILL"),console.log(` force-closed playwright host process ${o}`)}catch{}}}function J(e,n){if(n){let o=n.trim(),i=e.find(s=>s.id===o);if(!i)throw new Error(`no sim connected with id ${o}`);return i}let t=e.find(o=>o.isPrimary&&o.readyState==="open");if(t)return t;let r=e.find(o=>o.readyState==="open");if(r)return r;throw new Error("no sim connected")}function pt(e,n,t){let[r,o]=[e,n.url].map(i=>{if(!i)return i;try{let s=new URL(i);if(s.searchParams.has("sootsimConfig"))return s.searchParams.set("sootsimConfig","[redacted]"),s.toString()}catch{}return i});console.log(` ${t==="current sim"?"loaded":"opened"}: ${r} [${t}]`),console.log(` current sim: ${n.id}`),console.log(JSON.stringify({simId:n.id,url:o},null,2))}async function ft(e,n,t){if(t.includes("--no-describe"))return;let r=process.env.SOOTSIM_QUIET_TARGET_NOTICE;process.env.SOOTSIM_QUIET_TARGET_NOTICE="1";try{await yn(e,n,{stableMs:150,maxMs:400});let o=P(e,{commandTimeoutMs:3e3,simId:n,cliLabel:"open --describe",simIdSource:"flag"});try{let i=null;try{i=await o.send({type:"evaluate",code:Ge})}catch{}if(i&&!(i.flag===!0&&!i.loadingText&&Je(i))){let c=i.loadingText?`still showing "${i.loadingText}"`:i.flag!==!0?"guest ready event has not fired":i.targets<=0?"no visible app content is inspectable yet":"app tree is still stabilizing";console.log(` app still loading: ${c} (nodes: ${i.nodes}, targets: ${i.targets})`),console.log(" before interacting, run: rnx wait ready --max-ms 120000")}let a=`(async () => {
|
|
8
|
-
const t = window.__sootsimTest
|
|
9
|
-
const ms = window.SootSim?.bridges?.mainShell
|
|
10
|
-
if (!t) return null
|
|
11
|
-
let shell = null
|
|
12
|
-
try { shell = ms?.getState ? await ms.getState() : null } catch {}
|
|
13
|
-
const tree = await t.dumpTree(12, ${JSON.stringify({describe:!0,verbose:!1,filter:""})})
|
|
14
|
-
return { tree, shell }
|
|
15
|
-
})()`,l=await o.send({type:"evaluate",code:a});if(!l?.tree)return;if(console.log(""),l.shell?.state){let d=[`state=${l.shell.state}`,l.shell.activeApp?`app=${l.shell.activeApp}`:null].filter(Boolean);console.log(` shell: ${d.join(" ")}`)}console.log(l.tree)}finally{o.close()}}catch{}finally{r===void 0?delete process.env.SOOTSIM_QUIET_TARGET_NOTICE:process.env.SOOTSIM_QUIET_TARGET_NOTICE=r}}async function yn(e,n,t){let r=Date.now()+t.maxMs,o="(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()",i=P(e,{commandTimeoutMs:2e3,simId:n,simIdSource:"flag"});try{let s=-1,a=0;for(;Date.now()<r;){let l=-1;try{let d=await i.send({type:"evaluate",code:o});typeof d=="number"&&(l=d)}catch{}if(l>=0&&l===s){if(Date.now()-a>=t.stableMs)return}else s=l,a=Date.now();await y(50)}}finally{i.close()}}async function Sn(e,n={}){let t=E(e,{port:n.port,commandTimeoutMs:n.timeoutMs});t.positional.length!==1&&(console.error(" rnx open: expected exactly one <url-or-route>"),console.error(" examples: rnx open /settings | rnx open myapp://settings"),process.exit(1));let r;try{r=Nt(t.positional[0]??"")}catch(s){console.error(` rnx open: ${s instanceof Error?s.message:String(s)}`),process.exit(1)}let o=_(t),i=t.simId?` --sim ${t.simId}`:"";try{let s=await o.send({type:"call",path:"SootSim.bridges.test.openDeepLink",args:[r]});if(Ft(s)&&s.ok===!1)throw new Error(typeof s.error=="string"?s.error:"deep-link dispatch failed");console.log(` opened deep link: ${r}`)}catch(s){console.error(` link failed: ${s instanceof Error?s.message:String(s)}`),await A(o,{errorsCommand:`rnx get errors 5${i}`,warningsCommand:`rnx get warnings 5${i}`,requestsCommand:`rnx get requests 5${i}`}),process.exit(1)}finally{o.close()}}async function or(e,n={}){let t=E(e,{port:n.port,commandTimeoutMs:n.timeoutMs,stripBooleanFlags:["--new","--headless","--headed","--ephemeral","--hot","--no-hmr","--no-describe"],stripValueFlags:["--base-url","--replace","--driver","--profile","--cdp-port","--device","--viewport"]}),r=e.find((p,m)=>e[m-1]==="--profile"),o=e.includes("--ephemeral"),i=e.find((p,m)=>e[m-1]==="--cdp-port"),s=i?Number(i):void 0;i&&(!Number.isFinite(s)||s<=0)&&(console.error(` rnx open: --cdp-port must be a positive port number, got "${i}"`),process.exit(1)),r&&o&&(console.error(" rnx open: --profile cannot be combined with --ephemeral"),process.exit(1));let a=r?Ne(r).id:void 0,l=e.includes("--new")||!!a||o,d=Zt(e);l&&t.simIdSource==="flag"&&(console.error(" rnx open: --new, --profile, and --ephemeral cannot be combined with --sim"),process.exit(1));let c=t.positional[0]||"";if(jt(c)){l&&(console.error(" rnx open: deep links target the current app; remove --new, --profile, or --ephemeral"),process.exit(1)),await Sn(e,n);return}if(zt(c)){let p=(()=>{try{return I(new URL(c).hostname)}catch{return!1}})();console.log(" that\u2019s an rnx preview/build link \u2014 a full player page, not a driveable sim."),console.log(" opening it in your browser for viewing\u2026");try{await Ye(c,{background:!1})}catch(m){console.error(` could not launch a browser: ${m instanceof Error?m.message:String(m)}`),console.error(` open it yourself: ${c}`),process.exit(1)}console.log(p?" to drive it under the CLI, point `rnx open` at the app\u2019s dev port instead (e.g. `rnx open 8081`).":" the CLI can\u2019t drive a remote preview (the engine only attaches to the local bridge from localhost). to drive the app, run it locally and `rnx open <port>`.");return}let u=ht(c)?await be(c):void 0,g=await Xt(u),T=await He(g),N=T?.runtimeVersion,F=le(le(T?{...T,runtimeVersion:void 0}:void 0,n.runtimeConfig),d);N&&await en(N);let Q=e.find((p,m)=>e[m-1]==="--base-url");if(Q&&!t.explicitPort){let p=ae(Q);p&&(t.wsPort=p)}t.wsPort=await Ht(t.wsPort,t.explicitPort);let R=e.find((p,m)=>e[m-1]==="--driver")||"";R&&!lt(R)&&(console.error(` unknown driver "${R}" \u2014 run \`rnx list --drivers\``),process.exit(1));let S=lt(R)?R:"playwright",vt=At(e,S);s&&S!=="playwright"&&(console.error(" rnx open: --cdp-port is only honored by the playwright driver"),process.exit(1));let ve=e.includes("--hot"),ye=e.includes("--no-hmr");ve&&ye&&(console.error(" rnx open: --hot and --no-hmr cannot be combined"),process.exit(1));let yt=ve?!0:ye?!1:R!=="playwright",k=e.find((p,m)=>e[m-1]==="--device");k&&!(k in ie)&&(console.error(` rnx open: unknown device "${k}"`),console.error(` known devices: ${Re().join(", ")}`),process.exit(1));let Y=k?ie[k]:void 0,j=e.find((p,m)=>e[m-1]==="--viewport"),H=j?/^(\d+)x(\d+)$/.exec(j):null;j&&!H&&(console.error(` rnx open: --viewport must be <width>x<height>, got "${j}"`),process.exit(1));let St=H?{width:Number(H[1]),height:Number(H[2])}:void 0,W={hot:yt,device:k,resolvedBundle:u,project:g},xt=N?`http://localhost:${t.wsPort}/`:Q||nn(t.wsPort),x=tn(xt,N),Se=e.includes("--base-url");Oe(t.wsPort,x);let $t=B();if(!l){let p=_(t),m=t.simId?` --sim ${t.simId}`:"",ee=!1;try{let f=null,V=null;try{let h=await p.listSims();if(t.simIdSource==="saved")f=h.find(w=>w.id===$t&&w.readyState==="open"&&pe(w,S))??null,f||D();else if(t.simIdSource==="flag"&&(f=J(h,t.simId),!pe(f,S)))throw new Error(`sim ${f.id} is not managed by the ${S} driver`);if(!f&&t.simIdSource!=="flag"){V=await q(c,L(x,F),W);let w=new URL(V);w.searchParams.delete("inspectOpen"),f=h.find(v=>{if(v.readyState!=="open"||!v.url||!pe(v,S))return!1;try{let Ie=new URL(v.url);return Ie.searchParams.delete("inspectOpen"),Ie.toString()===w.toString()}catch{return!1}})??null}if(!f)if(t.simIdSource!=="flag")ee=!0;else throw new Error("no sim connected");if(!ee&&f){let w=Se||he(c)?x:dt(f,x),v=V??await q(c,L(w,F),W);p.send({type:"evaluate",simId:f.id,code:`window.location.href = ${JSON.stringify(v)}`}).catch(()=>{})}}catch(h){console.error(` open failed: ${h instanceof Error?h.message:String(h)}`),await A(p,{errorsCommand:`rnx get errors 5${m}`,warningsCommand:`rnx get warnings 5${m}`,requestsCommand:`rnx get requests 5${m}`}),process.exit(1)}if(!ee&&f){await y(1500);let h=await dn(t.wsPort,t.commandTimeoutMs,f.id);h||(console.error(" timed out waiting for current sim to load target"),process.exit(1)),h.bridge.close(),$(f.id);let w=Se||he(c)?x:dt(f,x),v=V??await q(c,L(w,F),W);return pt(v,{...f,url:v},"current sim"),await ft(t.wsPort,f.id,e),t.wsPort}}finally{p.close()}}let Pt=L(x,F),xe=`cli-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,$e=await cn(c,Pt,xe,W),Pe=Ee();Pe||(console.error(" could not resolve a stable owning process; refusing unsupervised sim host"),process.exit(1));let It=p=>p.url?.includes(`inspectOpen=${xe}`)??!1,U=Qe(S);U||(console.error(` unknown driver "${S}" \u2014 run \`rnx list --drivers\``),process.exit(1));let K=Lt(),b=await U.launch({url:$e,bridgePort:ae(x)??t.wsPort,headless:vt,profileId:a,ephemeralProfile:o,cdpPort:s,device:k,ownerPid:Pe,viewport:St??(Y?{width:Y.width+120,height:Y.height+60}:void 0),connectTimeoutMs:K.hostTimeoutMs});b.launched||(console.error(` ${U.name} driver: ${b.message}`),process.exit(1));let Z=await fn(t.wsPort,t.commandTimeoutMs,It,b.pid,{attempts:K.attempts,intervalMs:K.intervalMs});if(Z.kind==="host-exit"&&(mt(b),console.error(` ${U.name} host crashed \u2014 sim is no longer attached`),process.exit(1)),Z.kind==="timeout"){if(b.pid)try{process.kill(b.pid,"SIGTERM"),console.error(` closed ${U.name} host process ${b.pid}`)}catch{}mt(b),console.error(` timed out after ${K.timeoutMs}ms waiting for opened sim to connect`),process.exit(1)}let X=Z.sim;return $(X.id),wn(b),pt($e,X,`${U.name} driver`),await ft(t.wsPort,X.id,e),t.wsPort}async function bt(e,n={}){let t=E(e,{port:n.port,commandTimeoutMs:n.timeoutMs,stripBooleanFlags:["--force"]}),r=e.includes("--force"),o=_(t),i=t.simId?` --sim ${t.simId}`:"";try{try{let s=await o.listSims(),a=J(s,t.positional[0]||t.simId);if(a.lockedBy&&a.lockExpiresAt&&a.lockExpiresAt>Date.now()){let l=Math.max(0,Math.round((a.lockExpiresAt-Date.now())/1e3));a.lockedByKind==="user-active"&&(console.error(` refused: ${a.id} is locked by the active user (${l}s) \u2014 that's a live human tab`),console.error(" run `rnx open --new` for a fresh investigation sim"),process.exit(1)),r||(console.error(` refused: ${a.id} is leased by ${a.lockedBy} (${l}s)`),console.error(` \`sootsim use ${a.id} --force\` to take it, or \`rnx open --new\` for a fresh sim`),process.exit(1))}await o.focusSim(a.id),$(a.id),console.log(` using: ${a.id}`)}catch(s){console.error(` use failed: ${s instanceof Error?s.message:String(s)}`),await A(o,{errorsCommand:`rnx get errors 5${i}`,warningsCommand:`rnx get warnings 5${i}`,requestsCommand:`rnx get requests 5${i}`}),process.exit(1)}}finally{o.close()}}async function ir(e,n={}){await bt(e,n)}async function sr(e,n={}){await bt(e,n)}async function ar(e,n={}){let t=E(e,{port:n.port,commandTimeoutMs:n.timeoutMs,stripBooleanFlags:["--force"]}),r=e.includes("--force"),o=_(t);try{try{let i=await o.listSims(),s=J(i,t.positional[0]||t.simId),a=r&&s.lockedBy&&s.lockedByKind!=="user-active"?s.lockedBy:null,l=await o.claim(s.id,{force:r});$(s.id);let d=Math.max(0,Math.round((l.lockExpiresAt-Date.now())/1e3)),c=l.bootedCount>0?` (booted ${l.bootedCount})`:"";console.log(` claimed: ${l.simId} [${d}s]${c}`),a&&console.log(` took over from: ${a}`)}catch(i){if(i instanceof Te){let s=Math.max(0,Math.round(i.lock.expiresInMs/1e3));console.error(` claim failed: locked by ${i.lock.by} for ${s}s more`),console.error(" use --force to take it, or `rnx open --new` for a fresh sim"),process.exit(1)}console.error(` claim failed: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}finally{o.close()}}async function xn(e,n,t,r){if(r.length===0)return{closed:[],remaining:[]};await Promise.all(r.map(i=>e.closeSim(i).catch(()=>{})));let o=new Set(r);for(let i=0;i<40;i++){let s=[];try{let a=P(n,{commandTimeoutMs:t});try{s=(await a.listSims()).filter(d=>o.has(d.id)&&d.readyState==="open").map(d=>d.id)}finally{a.close()}}catch{s=[]}if(s.length===0)return{closed:[...o],remaining:[]};if(i===39)return{closed:[...o].filter(a=>!s.includes(a)),remaining:s};await y(250)}return{closed:[...o],remaining:[]}}function $n(e,n){let t=e.filter(u=>u.readyState==="open"),r=t.map(u=>u.id),o=n.explicitKeepId?.trim()||"",i=n.savedKeepId?.trim()||"",s=i?t.some(u=>u.id===i):!1,a=i&&!s?i:null,l=null,d=null,c=null;if(n.closeOthers)if(o){let u=t.find(g=>g.id===o);u?l=u.id:d=o}else if(i&&s)l=i;else{let u=t.find(g=>g.isPrimary)??t[0]??null;u&&(l=u.id,i&&!s&&(c=u.id))}return{openIds:r,keepId:l,targets:d?[]:r.filter(u=>u!==l),staleSavedId:a,missingExplicitKeepId:d,fallbackKeepId:c}}async function lr(e,n={}){let t=E(e,{port:n.port,commandTimeoutMs:n.timeoutMs,stripBooleanFlags:["--all","--others"]}),r=_(t),o=t.simId?` --sim ${t.simId}`:"",i=e.includes("--all"),s=e.includes("--others");if(i||s){try{let a=await r.listSims(),l=B(),d=t.positional[0]||(t.simIdSource==="flag"?t.simId:void 0),c=$n(a,{closeOthers:s,explicitKeepId:d,savedKeepId:l});if(c.staleSavedId&&D(),c.fallbackKeepId&&($(c.fallbackKeepId),console.log(` saved sim ${c.staleSavedId} is gone \u2014 keeping primary ${c.fallbackKeepId}`)),c.missingExplicitKeepId&&(console.error(` close failed: keep sim ${c.missingExplicitKeepId} is not connected; not closing other sims`),process.exit(1)),c.targets.length===0){console.log(c.keepId?` nothing to close \u2014 only the kept sim ${c.keepId} is connected`:c.staleSavedId?` nothing to close \u2014 no sims connected (cleared stale current sim ${c.staleSavedId})`:" nothing to close \u2014 no sims connected");return}let u=await xn(r,t.wsPort,t.commandTimeoutMs,c.targets);await ge(a,c.targets);let g=B();g&&u.closed.includes(g)&&(c.keepId?$(c.keepId):D());let T=` closed ${u.closed.length} sim(s)${c.keepId?` (kept ${c.keepId})`:""}`;console.log(T),u.remaining.length>0&&(console.error(` close failed: still connected: ${u.remaining.join(", ")}`),process.exit(1))}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),process.exit(1)}finally{r.close()}return}try{try{let a=await r.listSims(),l=J(a,t.positional[0]||t.simId),d=a.find(u=>u.id!==l.id&&u.readyState==="open");await r.closeSim(l.id),await gn(t.wsPort,t.commandTimeoutMs,l.id)||(await ge(a,[l.id]),console.error(` close failed: ${l.id} is still connected`),process.exit(1)),await ge(a,[l.id]),B()===l.id&&(d?$(d.id):D()),console.log(` closed: ${l.id}`)}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),await A(r,{errorsCommand:`rnx get errors 5${o}`,warningsCommand:`rnx get warnings 5${o}`,requestsCommand:`rnx get requests 5${o}`}),process.exit(1)}}finally{r.close()}}export{Lt as a,Nt as b,Ht as c,tr as d,tn as e,wt as f,nn as g,q as h,cn as i,un as j,nr as k,rr as l,fn as m,hn as n,wn as o,ge as p,Sn as q,or as r,ir as s,sr as t,ar as u,xn as v,$n as w,lr as x};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/*! rnx v0.1.352 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
|
-
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
import{a as $}from"./chunk-HF2FZ2WN.js";import{a as y}from"./chunk-S63ENXGH.js";import{spawn as b,spawnSync as u}from"child_process";import{chmodSync as v,copyFileSync as S,createWriteStream as T,existsSync as f,mkdirSync as x,rmSync as w,statSync as P,unlinkSync as E}from"fs";import{tmpdir as D}from"os";import{dirname as M,join as m,resolve as k}from"path";var h="https://contrast.dev/api/electron-release";function A(){let r=process.arch;if(process.platform==="darwin"){let o=r==="arm64"?"mac-arm64":"mac-x64",t=`sootsim-latest-${o}.dmg`;return{platform:o,filename:t,url:`${h}/${t}`,install:L}}if(process.platform==="linux"){let o=r==="arm64"?"linux-arm64":"linux-x64",t=`sootsim-latest-${o}.AppImage`;return{platform:o,filename:t,url:`${h}/${t}`,install:B}}if(process.platform==="win32"){let o="sootsim-latest-win-x64.exe";return{platform:"win-x64",filename:o,url:`${h}/${o}`,install:C}}return null}async function O({url:r,dest:o,onProgress:t}){let s=await fetch(r,{redirect:"follow"});if(!s.ok)throw new Error(`${s.status} ${s.statusText} (${r})`);let e=s.headers.get("content-length"),a=e?Number(e):null;if(!s.body)throw new Error(`empty response body (${r})`);x(M(o),{recursive:!0});let i=T(o),d=s.body.getReader(),c=0;try{for(;;){let{done:n,value:l}=await d.read();if(n)break;i.write(Buffer.from(l)),c+=l.byteLength,t?.(c,a)}}finally{await new Promise((n,l)=>{i.end(p=>p?l(p):n())})}}function I(r,o){let t=(r/1048576).toFixed(1);if(!o)return` ${t} MB`;let s=Math.min(100,Math.round(r/o*100)),e=(o/(1024*1024)).toFixed(1),a=24,i=Math.round(s/100*a);return` ${"\u2588".repeat(i)+"\u2591".repeat(a-i)} ${s}% ${t} / ${e} MB`}async function L(r){let o=u("hdiutil",["attach","-nobrowse","-readonly",r],{encoding:"utf8"});if(o.status!==0)throw new Error(`hdiutil attach failed: ${o.stderr||o.stdout}`.trim());let t=o.stdout.trim().split(`
|
|
5
|
-
`),e=t[t.length-1].split(" ").pop()?.trim();if(!e||!f(e))throw new Error(`could not determine dmg mount point (output: ${o.stdout})`);let a=m(e,"rnx.app");if(!f(a))throw u("hdiutil",["detach","-force",e]),new Error(`rnx.app not found inside ${e}`);let i="/Applications",d=k(process.env.HOME||"","Applications"),c=i;try{let g=m(i,`.sootsim-write-probe-${process.pid}`);u("touch",[g]),f(g)?w(g,{force:!0}):c=d}catch{c=d}c===d&&x(c,{recursive:!0});let n=m(c,"sootsim.app");f(n)&&w(n,{recursive:!0,force:!0});let l=u("cp",["-R",a,n]),p=u("hdiutil",["detach","-force",e]);if(l.status!==0)throw new Error(`copy to ${n} failed: ${l.stderr?.toString()||""}`.trim());return p.status!==0&&console.warn(` warning: failed to unmount ${e} (${p.stderr?.toString().trim()||"unknown error"})`),u("xattr",["-dr","com.apple.quarantine",n]),n}async function B(r){let o=k(process.env.HOME||"","Applications");x(o,{recursive:!0});let t=m(o,"sootsim.AppImage");return f(t)&&w(t,{force:!0}),S(r,t),E(r),v(t,493),t}async function C(r){return await new Promise((o,t)=>{let s=b("cmd",["/c","start",'""',"/wait",r],{stdio:"inherit"});s.once("error",t),s.once("exit",e=>{e===0?o():t(new Error(`installer exited with code ${e}`))})}),r}async function q(r){(r.includes("--help")||r.includes("-h"))&&(console.log(`
|
|
6
|
-
rnx desktop install \u2014 download and install the optional desktop GUI
|
|
7
|
-
|
|
8
|
-
the CLI + daemon are the canonical rnx surface; the GUI is optional.
|
|
9
|
-
if you just want to drive a running metro/expo dev server from the
|
|
10
|
-
terminal, you don't need this.
|
|
11
|
-
|
|
12
|
-
usage:
|
|
13
|
-
rnx desktop install [options]
|
|
14
|
-
|
|
15
|
-
options:
|
|
16
|
-
-y, --yes skip confirmation and install immediately
|
|
17
|
-
--force reinstall even if the companion is already present
|
|
18
|
-
|
|
19
|
-
examples:
|
|
20
|
-
rnx desktop install
|
|
21
|
-
rnx desktop install --yes
|
|
22
|
-
`),process.exit(0));let o=r.includes("--yes")||r.includes("-y")||process.env.SOOTSIM_NO_PROMPT==="1"||process.env.CI==="1"||!process.stdin.isTTY,t=r.includes("--force"),s=$();if(s&&!t){console.log(` rnx desktop already installed at: ${s.path}`),console.log(" pass --force to reinstall.");return}let e=A();if(e||(console.error(` no desktop build available for ${process.platform}/${process.arch}.`),console.error(" supported: darwin-arm64, darwin-x64, linux-x64, linux-arm64, win32-x64"),process.exit(1)),console.log(` platform: ${e.platform}`),console.log(` download: ${e.url}`),console.log(),!o){if(!await y("download and install now?",!0)){console.log(" cancelled.");return}console.log()}let a=m(D(),`sootsim-install-${Date.now()}`),i=m(a,e.filename),d=0;process.stdout.write(` downloading ${e.filename}...
|
|
23
|
-
`);try{await O({url:e.url,dest:i,onProgress:(n,l)=>{let p=Date.now();p-d<100&&n<(l??1/0)||(d=p,process.stdout.isTTY&&process.stdout.write(`\r\x1B[2K${I(n,l)}`))}})}catch(n){w(a,{recursive:!0,force:!0});let l=n instanceof Error?n.message:String(n);console.error(`
|
|
24
|
-
download failed: ${l}`),console.error(` the ${e.platform} desktop build may not be published yet, or your`),console.error(" network blocked the request. check your connection and try again later;"),console.error(" the CLI + daemon work without the desktop app (run: rnx --help)."),process.exit(1)}process.stdout.isTTY&&process.stdout.write(`
|
|
25
|
-
`);let c=P(i).size;console.log(` downloaded ${(c/(1024*1024)).toFixed(1)} MB`),console.log(),console.log(" installing...");try{let n=await e.install(i);console.log(` installed: ${n}`)}catch(n){console.error(` install failed: ${n instanceof Error?n.message:String(n)}`),console.error(` keeping download at ${i} for manual install.`),process.exit(1)}finally{w(a,{recursive:!0,force:!0})}console.log(),console.log(" next steps:"),console.log(" rnx desktop launch the desktop app"),console.log(" rnx open <target> open a demo or bundle in it")}export{q as a};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/*! rnx v0.1.352 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
|
-
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
import{randomUUID as k}from"node:crypto";import n from"node:fs";import{homedir as _}from"node:os";import i from"node:path";var $="SOOTSIM_HOME",I="active",B="daemon.json",M="dev-bridges",T="config.json",P=3e4;function s(){let e=process.env[$];return e&&e.length>0?i.resolve(e):i.join(_(),".sootsim")}function J(){if(process.env.SOOTSIM_FORCE_DAEMON_INSTALL==="1")return!1;let e=process.env.SOOTSIM_DEV;if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;let t=process.argv[1];if(!t)return!1;try{return n.realpathSync(t).includes(`${i.sep}packages${i.sep}sootsim${i.sep}`)}catch{return!1}}function U(){return process.env.SOOTSIM_FORCE_DAEMON_INSTALL==="1"?!1:process.env.IS_TAMAGUI_DEV==="1"}function oe(){return J()||U()}function S(){return i.join(s(),"runtimes")}function V(e){return i.join(S(),e)}function R(){return i.join(S(),I)}function x(){return i.join(s(),"electron")}function ce(){return i.join(x(),"userData")}function se(e){return i.join(x(),e)}function H(){return i.join(s(),"profiles")}function ue(){return i.join(s(),"camera-fixtures")}function G(){return i.join(s(),"daemon-app")}function K(){return i.join(G(),"SootSim Daemon.app")}function ae(){return i.join(K(),"Contents","MacOS","sootsim-daemon")}function X(){return i.join(s(),"cache")}function m(){return i.join(s(),B)}function p(){return i.join(s(),M)}function w(e){if(!Number.isInteger(e)||e<=0)throw new Error(`invalid development bridge port: ${e}`);return i.join(p(),`${e}.json`)}function D(){return i.join(s(),T)}function A(){try{let e=n.readFileSync(D(),"utf8"),t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}function O(e){v();let t=A(),r={...t,...e};e.settings&&typeof e.settings=="object"&&(r.settings={...t.settings&&typeof t.settings=="object"?t.settings:{},...e.settings});let c=`${D()}.tmp`;return n.writeFileSync(c,`${JSON.stringify(r,null,2)}
|
|
5
|
-
`,"utf8"),n.renameSync(c,D()),r}function fe(){let e=A().settings,t=e?.productAnalytics,r=e?.crashReports;return{productAnalytics:typeof t=="boolean"?t:!1,crashReports:typeof r=="boolean"?r:!1,configured:typeof t=="boolean"&&typeof r=="boolean"}}function le(e){O({settings:{productAnalytics:e.productAnalytics,crashReports:e.crashReports}})}function de(){let e=A().anonymousId;if(typeof e=="string"&&e.trim())return e;let t=`anon-cli-${k()}`;return O({anonymousId:t}),t}function y(){return i.join(s(),"runtime-upgraded.json")}function me(e){v();let t=`${y()}.tmp`;n.writeFileSync(t,`${JSON.stringify(e)}
|
|
6
|
-
`,"utf8"),n.renameSync(t,y())}function pe(){try{let e=n.readFileSync(y(),"utf8");n.unlinkSync(y());let t=JSON.parse(e);return typeof t?.to!="string"||!t.to?null:{from:typeof t.from=="string"?t.from:null,to:t.to,at:typeof t.at=="number"?t.at:0}}catch{return null}}function v(){n.mkdirSync(s(),{recursive:!0}),n.mkdirSync(S(),{recursive:!0}),n.mkdirSync(x(),{recursive:!0}),n.mkdirSync(H(),{recursive:!0}),n.mkdirSync(X(),{recursive:!0})}function q(){try{let e=n.readFileSync(R(),"utf8").trim();return e.length>0?e:null}catch{return null}}function ye(e){n.mkdirSync(S(),{recursive:!0}),n.writeFileSync(R(),`${e}
|
|
7
|
-
`,"utf8")}function ge(){let e=q();if(!e)return null;let t=V(e);try{if(n.statSync(t).isDirectory())return t}catch{}return null}var g=16*1024,z=3e4;function d(){try{let e=n.openSync(m(),"r");try{let t=Buffer.alloc(g),r=n.readSync(e,t,0,g,0),c=t.subarray(0,r).toString("utf8"),o=JSON.parse(c);return o&&o.schema===1&&typeof o.pid=="number"&&typeof o.bridgePort=="number"&&typeof o.runtimePort=="number"&&typeof o.startedAt=="number"&&typeof o.heartbeatAt=="number"&&(o.servedRuntimes===void 0||Array.isArray(o.servedRuntimes)&&o.servedRuntimes.every(u=>typeof u=="string"))?o:null}finally{n.closeSync(e)}}catch{return null}}function E(e){try{let t=JSON.parse(e);return t&&t.schema===1&&t.source==="vite-dev"&&typeof t.pid=="number"&&typeof t.bridgePort=="number"&&typeof t.runtimePort=="number"&&typeof t.cwd=="string"&&typeof t.startedAt=="number"&&typeof t.heartbeatAt=="number"&&(t.shellPort===void 0||typeof t.shellPort=="number")&&(t.servedRuntimes===void 0||Array.isArray(t.servedRuntimes)&&t.servedRuntimes.every(r=>typeof r=="string"))?t:null}catch{return null}}function W(){let e;try{e=n.readdirSync(p(),{withFileTypes:!0})}catch{return[]}let t=[];for(let r of e)if(!(!r.isFile()||!/^\d+\.json$/.test(r.name)))try{let c=i.join(p(),r.name),o=n.openSync(c,"r");try{let u=Buffer.alloc(g),a=n.readSync(o,u,0,g,0),h=E(u.subarray(0,a).toString("utf8"));h&&r.name===`${h.bridgePort}.json`&&t.push(h)}finally{n.closeSync(o)}}catch{}return t.sort((r,c)=>r.bridgePort-c.bridgePort)}function b(e,t=Date.now()){if(!e||t-e.heartbeatAt>P)return!1;try{return process.kill(e.pid,0),!0}catch{return!1}}function Y(e,t=Date.now()){if(!e||t-e.heartbeatAt>P)return!1;try{return process.kill(e.pid,0),!0}catch{return!1}}function Se(){let e=new Set,t=d();if(b(t)){t.activeRuntime&&e.add(t.activeRuntime);for(let r of t.servedRuntimes??[])e.add(r)}for(let r of W())if(Y(r))for(let c of r.servedRuntimes??[])e.add(c);return[...e].sort()}function Q(e){v();let t=m(),r=d();if(!r){if(j(e))return;throw new Error("another rnx daemon claimed the lockfile before this write")}if(!f(r,e))throw new Error("refusing to overwrite another rnx daemon lockfile");let c=`${t}.${e.pid}.${k()}.tmp`;n.writeFileSync(c,`${JSON.stringify(e,null,2)}
|
|
8
|
-
`,"utf8");try{let o=d();if(!o||!f(o,e))throw new Error("rnx daemon lock ownership changed during heartbeat");n.renameSync(c,t)}finally{try{n.unlinkSync(c)}catch{}}}function ve(e){n.mkdirSync(p(),{recursive:!0});let t=w(e.bridgePort),r=`${t}.${e.pid}.tmp`;n.writeFileSync(r,`${JSON.stringify(e,null,2)}
|
|
9
|
-
`,"utf8"),n.renameSync(r,t)}function f(e,t){return e.pid===t.pid&&e.startedAt===t.startedAt}function N(e){return e instanceof Error&&"code"in e&&Reflect.get(e,"code")==="EEXIST"}function j(e){let t=m(),r=`${t}.${e.pid}.${k()}.claim`;n.writeFileSync(r,`${JSON.stringify(e,null,2)}
|
|
10
|
-
`,"utf8");try{return n.linkSync(r,t),!0}catch(c){if(N(c))return!1;throw c}finally{try{n.unlinkSync(r)}catch{}}}function l(){return`${m()}.claim`}function C(e){try{let t=JSON.parse(e);if(t!==null&&typeof t=="object"&&typeof Reflect.get(t,"pid")=="number"&&typeof Reflect.get(t,"startedAt")=="number"&&typeof Reflect.get(t,"createdAt")=="number")return{pid:Reflect.get(t,"pid"),startedAt:Reflect.get(t,"startedAt"),createdAt:Reflect.get(t,"createdAt")}}catch{}return null}function F(){try{return C(n.readFileSync(l(),"utf8"))}catch{return null}}function L(e,t=Date.now()){if(t-e.createdAt>z)return!1;try{return process.kill(e.pid,0),!0}catch{return!1}}function Z(e){let t={pid:e.pid,startedAt:e.startedAt,createdAt:Date.now()},r=`${JSON.stringify(t)}
|
|
11
|
-
`;for(let c=0;c<8;c++){try{return n.writeFileSync(l(),r,{encoding:"utf8",flag:"wx"}),!0}catch(a){if(!N(a))throw a}let o=F();if(o&&f(o,t))return!0;if(o&&L(o))return!1;let u;try{u=n.readFileSync(l(),"utf8");let a=C(u);if(a&&L(a))return!1;if(n.readFileSync(l(),"utf8")!==u)continue;n.unlinkSync(l())}catch{}}return!1}function ee(e){try{let t=F();if(!t||!f(t,e))return;n.unlinkSync(l())}catch{}}function he(e){if(v(),!Z(e))return!1;try{let t=d();if(t&&f(t,e))return Q(e),!0;if(t&&b(t))return!1;if(t){let r=d();if(!r||!f(r,t)||b(r))return!1;try{n.unlinkSync(m())}catch{return!1}}return j(e)}finally{ee(e)}}function De(e){try{let t=d();if(!t||!f(t,e))return;n.unlinkSync(m())}catch{}}function be(e){try{let t=w(e.bridgePort),r=E(n.readFileSync(t,"utf8"));if(r?.pid!==e.pid||r.startedAt!==e.startedAt)return;n.unlinkSync(t)}catch{}}export{$ as a,I as b,B as c,M as d,T as e,P as f,s as g,J as h,U as i,oe as j,S as k,V as l,R as m,x as n,ce as o,se as p,H as q,ue as r,G as s,K as t,ae as u,X as v,m as w,p as x,w as y,D as z,A,O as B,fe as C,le as D,de as E,y as F,me as G,pe as H,v as I,q as J,ye as K,ge as L,d as M,W as N,b as O,Y as P,Se as Q,Q as R,ve as S,he as T,De as U,be as V};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/*! rnx v0.1.352 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
|
-
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
import{execFileSync as h,spawn as g}from"child_process";import{existsSync as s,readdirSync as k}from"fs";import{dirname as m,join as l,resolve as a}from"path";import{fileURLToPath as w}from"url";var c;function p(){if(c!==void 0)return c;try{c=m(w(import.meta.resolve("sootsim-engine/package.json")))}catch{c=null}return c}var v="dev.sootsim.simulator";function I(){let e=p();if(!e)return null;let n=l(e,"dist-electron/main.cjs");if(!s(n))return null;let i=P(e);return i?{path:i,platform:process.platform,kind:"dev-electron",engineDir:e}:null}function x(){let e=p();return e?s(l(e,"src-electron/main.ts")):!1}function P(e){let n=e;for(let i=0;i<6;i++){let t=l(n,"node_modules/.bin/electron");if(s(t))return t;let r=m(n);if(r===n)break;n=r}return null}function b(){let e=p(),i=["/Applications/sootsim.app",a(process.env.HOME||"","Applications/sootsim.app"),...e?[a(e,"app/sootsim.app")]:[]].find(t=>s(t));if(i)return{path:i,platform:"darwin",kind:"mac-app"};try{let t=h("mdfind",[`kMDItemCFBundleIdentifier == "${v}"`],{encoding:"utf8",timeout:3e3}).trim();if(t)return{path:t.split(`
|
|
5
|
-
`)[0],platform:"darwin",kind:"mac-app"}}catch{}return null}function f(e){if(!s(e))return null;let n=k(e).filter(i=>i.startsWith("sootsim")&&i.endsWith(".AppImage")).sort().reverse()[0];return n?l(e,n):null}function D(){let e=p(),i=[a(process.env.HOME||"","Applications/sootsim.AppImage"),a(process.env.HOME||"",".local/bin/sootsim.AppImage"),"/opt/sootsim/sootsim.AppImage","/opt/sootsim/sootsim",...e?[a(e,"app/sootsim.AppImage"),a(e,"release/linux-unpacked/sootsim")]:[]].find(r=>s(r));if(i)return{path:i,platform:"linux",kind:i.endsWith(".AppImage")?"linux-appimage":"linux-binary"};let t=e?f(a(e,"app"))||f(a(e,"release")):null;return t?{path:t,platform:"linux",kind:"linux-appimage"}:null}function C(){let e=I();if(e)return e;if(x()){let n=p(),i=l(n,"dist-electron/main.cjs");return s(i)?console.error(` no node_modules/.bin/electron found near ${n}. run \`bun install\`.`):console.error(` dist-electron/main.cjs missing in ${n}.
|
|
6
|
-
run: bun run --cwd packages/sootsim-engine build:electron-main
|
|
7
|
-
(or keep it fresh with: bun run watch:sootsim:electron-main)`),null}return process.platform==="darwin"?b():process.platform==="linux"?D():null}async function d(e,n,i={}){let t=i.inheritStdio?["ignore","inherit","inherit"]:"ignore";await new Promise((r,o)=>{let u=g(e,n,{detached:!0,stdio:t});u.once("error",o),u.once("spawn",()=>{u.unref(),r()})})}async function O(e,n=C(),i={}){if(!n)return{launched:!1};let t=[];if(i.device&&t.push(`--device=${i.device}`),i.profileId&&t.push(`--profile=${i.profileId}`),i.ephemeralProfile&&t.push("--ephemeral-profile"),i.ownerPid&&i.ownerPid>1&&t.push(`--owner-pid=${i.ownerPid}`),n.kind==="mac-app"){let o=["-g","-a",n.path];return e&&o.push(A(e,i)),t.length>0&&o.push("--args",...t),await d("open",o),{launched:!0,via:"mac-app",target:n.path}}if(n.kind==="dev-electron"){let o=["--no-sandbox",n.engineDir||p()];return e&&o.push(e),t.length>0&&o.push(...t),await d(n.path,o,{inheritStdio:!0}),{launched:!0,via:"dev-electron",target:n.path}}let r=[];return e&&r.push(e),t.length>0&&r.push(...t),await d(n.path,r),{launched:!0,via:n.kind,target:n.path}}function A(e,n){if(!n.profileId&&!n.ephemeralProfile&&!n.ownerPid)return e;let i=new URL("sootsim://dev");return i.searchParams.set("url",e),n.profileId&&i.searchParams.set("profile",n.profileId),n.ephemeralProfile&&i.searchParams.set("ephemeral","1"),n.ownerPid&&n.ownerPid>1&&i.searchParams.set("ownerPid",String(n.ownerPid)),i.toString()}export{C as a,O as b};
|