rnxsim 0.1.381 → 0.1.382
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 +19 -6
- package/cli/app-fonts.ts +1 -1
- package/cli/bin.ts +118 -26
- package/cli/bridge-diagnostics.ts +1 -1
- package/cli/bridge-flow-runner.ts +9 -9
- package/cli/browser-evals.ts +3 -3
- package/cli/cli-update.ts +261 -0
- package/cli/cloud-client.ts +407 -0
- package/cli/cloud-dispatch.ts +165 -0
- package/cli/cloud-session.ts +156 -0
- package/cli/command-contract.ts +2 -2
- package/cli/command-registry.ts +9 -0
- package/cli/commands/agent-wrapper.ts +4 -4
- package/cli/commands/agent.ts +3 -3
- package/cli/commands/box/checkout-plane.ts +16 -8
- package/cli/commands/box/rnx-command.ts +2 -2
- package/cli/commands/box/search-command.ts +2 -2
- package/cli/commands/box.ts +123 -70
- package/cli/commands/config.ts +3 -2
- package/cli/commands/control.ts +6 -6
- package/cli/commands/cpu-profile.ts +2 -2
- package/cli/commands/daemon.ts +7 -7
- package/cli/commands/debug.ts +2 -2
- package/cli/commands/detox.ts +7 -7
- package/cli/commands/diagnose.ts +1 -1
- package/cli/commands/electron.ts +1 -1
- package/cli/commands/film.ts +1 -1
- package/cli/commands/flow.ts +4 -4
- package/cli/commands/inspect/core.ts +58 -7
- package/cli/commands/inspect/env.ts +5 -3
- package/cli/commands/inspect/shared.ts +2 -1
- package/cli/commands/inspect/wait-event.ts +1 -1
- package/cli/commands/inspect/wait-ready.ts +15 -5
- package/cli/commands/inspect.ts +31 -9
- package/cli/commands/install-desktop.ts +2 -2
- package/cli/commands/maestro.ts +3 -3
- package/cli/commands/permissions.ts +1 -1
- package/cli/commands/platform.ts +91 -0
- package/cli/commands/record.ts +3 -3
- package/cli/commands/report-issue.ts +1 -1
- package/cli/commands/runtime.ts +1 -1
- package/cli/commands/screenshot-mode.ts +1 -1
- package/cli/commands/screenshot.ts +25 -0
- package/cli/commands/serve.ts +1 -1
- package/cli/commands/skills.ts +1 -1
- package/cli/commands/timeline.ts +1 -1
- package/cli/commands/upgrade.ts +8 -34
- package/cli/commands/upload.ts +3 -3
- package/cli/commands/version.ts +14 -3
- package/cli/commands/what-happened.ts +2 -2
- package/cli/current-sim.ts +43 -30
- package/cli/desktop-companion.ts +1 -1
- package/cli/drivers/electron.ts +1 -1
- package/cli/drivers/playwright.ts +3 -3
- package/cli/drivers/types.ts +4 -4
- package/cli/flow-file.ts +3 -3
- package/cli/help-core.ts +18 -11
- package/cli/hidden-runtime-alias.ts +1 -1
- package/cli/hints.ts +2 -2
- package/cli/maestro-js.ts +2 -2
- package/cli/outbound-endpoints.ts +40 -6
- package/cli/parse-args.ts +1 -1
- package/cli/registry.ts +1 -1
- package/cli/resolve-assets.ts +2 -2
- package/cli/secure-file.ts +31 -0
- package/cli/shell-init.ts +98 -0
- package/cli/ws-bridge.ts +18 -8
- package/detox/expectations.ts +1 -1
- package/detox/gestures.ts +3 -3
- package/detox/index.ts +3 -3
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +15 -8
- package/dist-lib/bridge-contract-input.mjs +15 -8
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +107 -0
- package/dist-lib/capture-contract.mjs +80 -0
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +32 -0
- package/dist-lib/cloud-contract.mjs +7 -0
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +4 -4
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +9 -1
- package/dist-lib/host/bridge-host.cjs +15 -10
- 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 +248 -73
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +44 -6
- package/dist-lib/sdk.mjs +44 -6
- package/dist-lib/skills.cjs +435 -155
- package/dist-lib/vite.cjs +1 -1
- package/package.json +20 -4
- package/scripts/dev-server-scanner.ts +3 -3
- package/skills/contrast/SKILL.md +1 -1
- package/skills/rnx-perf/SKILL.md +68 -52
- package/src/app-url.ts +2 -3
- package/src/bridge-contract-input.ts +17 -6
- package/src/bridge-contract.ts +25 -4
- package/src/capture-contract.ts +423 -0
- package/src/cloud-contract.ts +15 -0
- package/src/home-paths.ts +9 -3
- package/src/host/agent-host.ts +1 -1
- package/src/host/bridge-host.ts +13 -11
- package/src/host/plane-host.ts +2 -2
- package/src/index.ts +21 -0
- package/src/native-dev-bundle-url.ts +2 -2
- package/src/screenshots/orchestrate.ts +1 -1
- package/src/screenshots/org-deck.ts +1 -1
- package/src/settings-bundle.ts +1 -1
- package/src/sim-client.ts +4 -0
- package/src/vite-plugin-one.ts +2 -2
- package/src/vite-plugin.ts +1 -1
- package/cli/commands/box/cloud-box.ts +0 -294
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.382 | (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;
|
|
@@ -1808,9 +1808,9 @@ var init_registry = __esm({
|
|
|
1808
1808
|
coverage: 0.97,
|
|
1809
1809
|
coverageSource: "estimated",
|
|
1810
1810
|
capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native-reanimated"],
|
|
1811
|
-
note: "core animations, gestures, scroll, layout transitions, keyboard, sensors, reduced motion, native view property reads, and direct static style snapshots",
|
|
1812
|
-
working: "useSharedValue, useAnimatedStyle/Props/Reaction, useDerivedValue, useAnimatedScrollHandler, useScrollViewOffset, useFrameCallback, useAnimatedRef, useAnimatedKeyboard, useAnimatedSensor, useReducedMotion, entering/exiting/layout transitions, withTiming/Spring/Decay/Delay/Sequence/Repeat/Clamp, interpolate, interpolateColor, runOnJS/UI, measure, scrollTo, getViewProp (layout, opacity, zIndex, backgroundColor, boxShadow), direct setViewStyle snapshots, Easing, createAnimatedComponent, Animated.View/Text/Image/ScrollView/FlatList",
|
|
1813
|
-
missing: "Reanimated 4
|
|
1811
|
+
note: "core animations, gestures, scroll, layout transitions, common CSS opacity and transform transitions and keyframes, keyboard, sensors, reduced motion, native view property reads, and direct static style snapshots",
|
|
1812
|
+
working: "useSharedValue, useAnimatedStyle/Props/Reaction, useDerivedValue, useAnimatedScrollHandler, useScrollViewOffset, useFrameCallback, useAnimatedRef, useAnimatedKeyboard, useAnimatedSensor, useReducedMotion, entering/exiting/layout transitions, common CSS opacity and transform transitions with continuous interruption and settled endpoints, opacity and transform keyframes with retained forwards fill, withTiming/Spring/Decay/Delay/Sequence/Repeat/Clamp, interpolate, interpolateColor, runOnJS/UI, measure, scrollTo, getViewProp (layout, opacity, zIndex, backgroundColor, boxShadow), direct setViewStyle snapshots, Easing, createAnimatedComponent, Animated.View/Text/Image/ScrollView/FlatList",
|
|
1813
|
+
missing: "Reanimated 4 CSS transitions and keyframes beyond opacity and transform remain incomplete"
|
|
1814
1814
|
}
|
|
1815
1815
|
]
|
|
1816
1816
|
},
|
|
@@ -1991,7 +1991,7 @@ var init_registry = __esm({
|
|
|
1991
1991
|
capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native-keyboard-controller"],
|
|
1992
1992
|
note: "native bindings stubbed (KeyboardControllerNative, KeyboardEvents, FocusedInputEvents, WindowDimensionsEvents, KeyboardControllerView + sibling native views); upstream pure-JS components, hooks, animated module, and KeyboardAvoidingView resolve from node_modules unchanged",
|
|
1993
1993
|
working: "every upstream JS export runs through reanimated worklets; Android KeyboardGestureArea drives the existing keyboard owner through drag progress, velocity/distance settling, cancellation, focus retention, and cleanup; supported exports include KeyboardProvider, KeyboardAvoidingView, KeyboardStickyView, KeyboardAwareScrollView, KeyboardToolbar, KeyboardGestureArea, useReanimatedKeyboardAnimation, useKeyboardAnimation, useKeyboardHandler, useGenericKeyboardHandler, useKeyboardController, useKeyboardState, useKeyboardContext, useReanimatedFocusedInput, useFocusedInputHandler, useResizeMode, useWindowDimensions, KeyboardEvents, FocusedInputEvents, WindowDimensionsEvents resize events, KeyboardController (dismiss/setFocusTo/isVisible/state/preload/setInputMode/setDefaultMode), KeyboardControllerView, OverKeyboardView, KeyboardBackgroundView, KeyboardExtender, ClippingScrollView, KeyboardToolbarGroupView, and AndroidSoftInputModes",
|
|
1994
|
-
missing: "
|
|
1994
|
+
missing: "KeyboardGestureArea lacks its iOS textInputNativeID/offset effect; OverKeyboardView, KeyboardBackgroundView, and KeyboardExtender are passthrough views without their native platform effects"
|
|
1995
1995
|
}
|
|
1996
1996
|
]
|
|
1997
1997
|
},
|
|
@@ -3458,9 +3458,9 @@ var init_registry = __esm({
|
|
|
3458
3458
|
{
|
|
3459
3459
|
range: ">=13.0.0",
|
|
3460
3460
|
coverage: 0.8,
|
|
3461
|
-
note: 'native-seam: upstream expo-calendar JS runs from the bundle over an in-memory EventKit-shaped store seeded faithfully to a fresh iOS Simulator \u2014 a writable local "Calendar" on the "Default" local source plus the always-present read-only "Birthdays" calendar, so getCalendarsAsync/getDefaultCalendarAsync match what a real RN app sees on the conformance Simulator (no sootsim brand names leak into guest calendar pickers). create/read/update/delete then mutate that store like EKEventStore.',
|
|
3462
|
-
working: 'reference-Simulator default calendar set (writable "Calendar" + read-only "Birthdays", faithful "Default" local source); real RN + sootsim validated event permission/create/read/update/range-query/attendee-read/delete smoke
|
|
3463
|
-
missing: 'real EventKit / CalendarContract access (the in-memory store does not surface events the user actually owns), calendar sync across processes/reloads, native calendar UI dialogs (presentEvent/createEventDialog), recurrence rule expansion
|
|
3461
|
+
note: 'native-seam: upstream expo-calendar JS runs from the bundle over an in-memory EventKit-shaped store seeded faithfully to a fresh iOS Simulator \u2014 a writable local "Calendar" on the "Default" local source plus the always-present read-only "Birthdays" calendar, so getCalendarsAsync/getDefaultCalendarAsync match what a real RN app sees on the conformance Simulator (no sootsim brand names leak into guest calendar pickers). create/read/update/delete then mutate that store like EKEventStore. daily recurrence queries expand lazily inside the requested range and preserve local wall times across named-zone offset changes.',
|
|
3462
|
+
working: 'reference-Simulator default calendar set (writable "Calendar" + read-only "Birthdays", faithful "Default" local source); real RN + sootsim validated event permission/create/read/update/range-query/attendee-read/delete smoke; upstream enums and JS validation, create/update/delete calendars, create/list/get/update/delete events with date-range filtering; sootsim-validated bounded daily recurrence expansion with interval/count rules, inclusive overlap boundaries, named time zones, and whole-series update/delete; attendee reads, create/list/get/update/delete reminders, open/edit dialog functions safely resolve, all permission functions',
|
|
3463
|
+
missing: 'real EventKit / CalendarContract access (the in-memory store does not surface events the user actually owns), calendar sync across processes/reloads, native calendar UI dialogs (presentEvent/createEventDialog), weekly/monthly/yearly and advanced recurrence rule expansion, detached-instance and future-split mutation semantics, attendee response/availability semantics, exact per-iOS-version Simulator calendar set (the seeded "Calendar"/"Birthdays" pair is the stable baseline)'
|
|
3464
3464
|
}
|
|
3465
3465
|
]
|
|
3466
3466
|
},
|
|
@@ -14147,7 +14147,7 @@ function scanDepsWithData(pkg, data) {
|
|
|
14147
14147
|
version,
|
|
14148
14148
|
coverage: 0.3,
|
|
14149
14149
|
status: "auto-stub",
|
|
14150
|
-
note: "not yet verified; it may work through
|
|
14150
|
+
note: "not yet verified; it may work through rnx's generic native seam",
|
|
14151
14151
|
rnx
|
|
14152
14152
|
});
|
|
14153
14153
|
continue;
|
|
@@ -15689,6 +15689,7 @@ var init_cli_version = __esm({
|
|
|
15689
15689
|
var home_paths_exports = {};
|
|
15690
15690
|
__export(home_paths_exports, {
|
|
15691
15691
|
ACTIVE_RUNTIME_FILE: () => ACTIVE_RUNTIME_FILE,
|
|
15692
|
+
CLI_UPDATE_FILE: () => CLI_UPDATE_FILE,
|
|
15692
15693
|
CONFIG_FILE: () => CONFIG_FILE,
|
|
15693
15694
|
DAEMON_HEARTBEAT_STALE_MS: () => DAEMON_HEARTBEAT_STALE_MS,
|
|
15694
15695
|
DAEMON_LOCKFILE: () => DAEMON_LOCKFILE,
|
|
@@ -15699,6 +15700,7 @@ __export(home_paths_exports, {
|
|
|
15699
15700
|
cacheDir: () => cacheDir,
|
|
15700
15701
|
cameraFixturesDir: () => cameraFixturesDir,
|
|
15701
15702
|
claimDaemonLockfile: () => claimDaemonLockfile,
|
|
15703
|
+
cliUpdateFilePath: () => cliUpdateFilePath,
|
|
15702
15704
|
configFilePath: () => configFilePath,
|
|
15703
15705
|
consumeRuntimeUpgradeNotice: () => consumeRuntimeUpgradeNotice,
|
|
15704
15706
|
daemonAppBundlePath: () => daemonAppBundlePath,
|
|
@@ -15817,6 +15819,9 @@ function devBridgeLockfilePath(bridgePort) {
|
|
|
15817
15819
|
function configFilePath() {
|
|
15818
15820
|
return import_node_path4.default.join(rnxHomeDir(), CONFIG_FILE);
|
|
15819
15821
|
}
|
|
15822
|
+
function cliUpdateFilePath() {
|
|
15823
|
+
return import_node_path4.default.join(rnxHomeDir(), CLI_UPDATE_FILE);
|
|
15824
|
+
}
|
|
15820
15825
|
function readSharedConfig() {
|
|
15821
15826
|
try {
|
|
15822
15827
|
const raw = import_node_fs4.default.readFileSync(configFilePath(), "utf8");
|
|
@@ -16200,7 +16205,7 @@ function removeDevBridgeLockfile(owner) {
|
|
|
16200
16205
|
} catch {
|
|
16201
16206
|
}
|
|
16202
16207
|
}
|
|
16203
|
-
var import_node_crypto, import_node_fs4, import_node_os, import_node_path4, RNX_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;
|
|
16208
|
+
var import_node_crypto, import_node_fs4, import_node_os, import_node_path4, RNX_HOME_ENV, ACTIVE_RUNTIME_FILE, DAEMON_LOCKFILE, DEV_BRIDGES_DIR, CONFIG_FILE, CLI_UPDATE_FILE, DAEMON_HEARTBEAT_STALE_MS, CURRENT_ONBOARDING_VERSION, DAEMON_LOCKFILE_MAX_BYTES, DAEMON_CLAIM_STALE_MS;
|
|
16204
16209
|
var init_home_paths = __esm({
|
|
16205
16210
|
"src/home-paths.ts"() {
|
|
16206
16211
|
"use strict";
|
|
@@ -16213,6 +16218,7 @@ var init_home_paths = __esm({
|
|
|
16213
16218
|
DAEMON_LOCKFILE = "daemon.json";
|
|
16214
16219
|
DEV_BRIDGES_DIR = "dev-bridges";
|
|
16215
16220
|
CONFIG_FILE = "config.json";
|
|
16221
|
+
CLI_UPDATE_FILE = "cli-update.json";
|
|
16216
16222
|
DAEMON_HEARTBEAT_STALE_MS = 3e4;
|
|
16217
16223
|
CURRENT_ONBOARDING_VERSION = 1;
|
|
16218
16224
|
DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
|
|
@@ -18560,7 +18566,7 @@ var init_open_url = __esm({
|
|
|
18560
18566
|
}
|
|
18561
18567
|
});
|
|
18562
18568
|
|
|
18563
|
-
// ../
|
|
18569
|
+
// ../rnx-box/src/planeProtocol.ts
|
|
18564
18570
|
function encodeBase64(bytes) {
|
|
18565
18571
|
let binary = "";
|
|
18566
18572
|
const CHUNK = 32768;
|
|
@@ -18635,47 +18641,47 @@ async function dispatchPlaneCommand(plane, type, msg, mutationOptions) {
|
|
|
18635
18641
|
}
|
|
18636
18642
|
var PLANE_FLAG_READ_ONLY, PLANE_FLAG_BINARY;
|
|
18637
18643
|
var init_planeProtocol = __esm({
|
|
18638
|
-
"../
|
|
18644
|
+
"../rnx-box/src/planeProtocol.ts"() {
|
|
18639
18645
|
"use strict";
|
|
18640
18646
|
PLANE_FLAG_READ_ONLY = 1;
|
|
18641
18647
|
PLANE_FLAG_BINARY = 2;
|
|
18642
18648
|
}
|
|
18643
18649
|
});
|
|
18644
18650
|
|
|
18645
|
-
// ../
|
|
18651
|
+
// ../rnx-box/src/projectFileCache.ts
|
|
18646
18652
|
var init_projectFileCache = __esm({
|
|
18647
|
-
"../
|
|
18653
|
+
"../rnx-box/src/projectFileCache.ts"() {
|
|
18648
18654
|
"use strict";
|
|
18649
18655
|
}
|
|
18650
18656
|
});
|
|
18651
18657
|
|
|
18652
|
-
// ../
|
|
18658
|
+
// ../rnx-box/src/planeClient.ts
|
|
18653
18659
|
var init_planeClient = __esm({
|
|
18654
|
-
"../
|
|
18660
|
+
"../rnx-box/src/planeClient.ts"() {
|
|
18655
18661
|
"use strict";
|
|
18656
18662
|
init_planeProtocol();
|
|
18657
18663
|
init_projectFileCache();
|
|
18658
18664
|
}
|
|
18659
18665
|
});
|
|
18660
18666
|
|
|
18661
|
-
// ../
|
|
18667
|
+
// ../rnx-box/src/projectFilePlaneRpc.ts
|
|
18662
18668
|
var init_projectFilePlaneRpc = __esm({
|
|
18663
|
-
"../
|
|
18669
|
+
"../rnx-box/src/projectFilePlaneRpc.ts"() {
|
|
18664
18670
|
"use strict";
|
|
18665
18671
|
init_planeProtocol();
|
|
18666
18672
|
}
|
|
18667
18673
|
});
|
|
18668
18674
|
|
|
18669
|
-
// ../
|
|
18675
|
+
// ../rnx-box/src/planeTransport.browser.ts
|
|
18670
18676
|
var init_planeTransport_browser = __esm({
|
|
18671
|
-
"../
|
|
18677
|
+
"../rnx-box/src/planeTransport.browser.ts"() {
|
|
18672
18678
|
"use strict";
|
|
18673
18679
|
}
|
|
18674
18680
|
});
|
|
18675
18681
|
|
|
18676
|
-
// ../
|
|
18682
|
+
// ../rnx-box/src/plane.ts
|
|
18677
18683
|
var init_plane = __esm({
|
|
18678
|
-
"../
|
|
18684
|
+
"../rnx-box/src/plane.ts"() {
|
|
18679
18685
|
"use strict";
|
|
18680
18686
|
init_planeProtocol();
|
|
18681
18687
|
init_planeClient();
|
|
@@ -18719,9 +18725,11 @@ var init_checkout_plane = __esm({
|
|
|
18719
18725
|
// long a wedged git is waited on, never whether it is waited on, so proving
|
|
18720
18726
|
// the kill does not have to cost the production deadline.
|
|
18721
18727
|
listTimeoutMs;
|
|
18728
|
+
trackedOnly;
|
|
18722
18729
|
constructor(root, options = {}) {
|
|
18723
18730
|
this.root = import_node_path10.default.resolve(root);
|
|
18724
18731
|
this.listTimeoutMs = options.listTimeoutMs ?? LIST_FILES_TIMEOUT_MS;
|
|
18732
|
+
this.trackedOnly = options.trackedOnly ?? false;
|
|
18725
18733
|
}
|
|
18726
18734
|
index() {
|
|
18727
18735
|
return this.entries;
|
|
@@ -18729,7 +18737,8 @@ var init_checkout_plane = __esm({
|
|
|
18729
18737
|
async refresh() {
|
|
18730
18738
|
let stdout;
|
|
18731
18739
|
try {
|
|
18732
|
-
|
|
18740
|
+
const args = this.trackedOnly ? ["ls-files", "-z"] : ["ls-files", "-co", "--exclude-standard", "-z"];
|
|
18741
|
+
stdout = (0, import_node_child_process5.execFileSync)("git", args, {
|
|
18733
18742
|
cwd: this.root,
|
|
18734
18743
|
encoding: "utf8",
|
|
18735
18744
|
maxBuffer: 64 * 1024 * 1024,
|
|
@@ -18749,7 +18758,7 @@ var init_checkout_plane = __esm({
|
|
|
18749
18758
|
}
|
|
18750
18759
|
if (stdout.length === 0) {
|
|
18751
18760
|
throw new CheckoutRequiresGitError(
|
|
18752
|
-
`git listed no files in ${this.root}. either
|
|
18761
|
+
`git listed no ${this.trackedOnly ? "tracked " : ""}files in ${this.root}. either the checkout contains no eligible files, or this machine could not read the child process's output.`
|
|
18753
18762
|
);
|
|
18754
18763
|
}
|
|
18755
18764
|
const next = /* @__PURE__ */ new Map();
|
|
@@ -19490,8 +19499,8 @@ var init_bridge_host = __esm({
|
|
|
19490
19499
|
static USER_BOOT_LEASE_TTL_MS = 6e4;
|
|
19491
19500
|
static SIM_RECONNECT_TTL_MS = 3e4;
|
|
19492
19501
|
// abandoned-tab GC. the ws heartbeat only reaps sims whose socket went
|
|
19493
|
-
// dead — but a background tab from a prior `
|
|
19494
|
-
// keeps its socket alive (the page still pongs) forever, so `
|
|
19502
|
+
// dead — but a background tab from a prior `rnx open` / QA / test run
|
|
19503
|
+
// keeps its socket alive (the page still pongs) forever, so `rnx list`
|
|
19495
19504
|
// accretes dozens of zombie sims that all time out on every command (QA
|
|
19496
19505
|
// F21-3, carried F19-2). reap a sim only when it is provably nobody's:
|
|
19497
19506
|
// not primary, not user-focused, no CLI attached, no active lease, and no
|
|
@@ -19499,7 +19508,7 @@ var init_bridge_host = __esm({
|
|
|
19499
19508
|
// terminal 4001 code, so the client closes the abandoned window instead
|
|
19500
19509
|
// of reconnecting the zombie straight back in.
|
|
19501
19510
|
static SIM_IDLE_REAP_TTL_MS = 30 * 6e4;
|
|
19502
|
-
// automation sims (spawned by the playwright driver: `
|
|
19511
|
+
// automation sims (spawned by the playwright driver: `rnx open --driver
|
|
19503
19512
|
// playwright`, the factory/screenshot capture path — `meta.sootsimHostDriver
|
|
19504
19513
|
// === 'playwright'`) are unattended one-shot browsers, never a human's tab. a
|
|
19505
19514
|
// capture run opens one per slide/app/retry and the 30-min human/dev TTL lets
|
|
@@ -19529,7 +19538,7 @@ var init_bridge_host = __esm({
|
|
|
19529
19538
|
// dropped, sim crashed) leave their server-side WebSocket sitting "open"
|
|
19530
19539
|
// forever. ping every WS_HEARTBEAT_INTERVAL_MS; if the previous round's
|
|
19531
19540
|
// ping was never answered, terminate(). that fires 'close' which runs the
|
|
19532
|
-
// sim-cleanup path and stops `
|
|
19541
|
+
// sim-cleanup path and stops `rnx list` from showing 8 zombie
|
|
19533
19542
|
// sims that all time out on every command.
|
|
19534
19543
|
wsHeartbeatTimer = null;
|
|
19535
19544
|
wsIsAlive = /* @__PURE__ */ new WeakMap();
|
|
@@ -20733,7 +20742,7 @@ var init_bridge_host = __esm({
|
|
|
20733
20742
|
this.sweepRestorableSims(now);
|
|
20734
20743
|
this.reapIdleSims(now);
|
|
20735
20744
|
}
|
|
20736
|
-
// GC abandoned sims so `
|
|
20745
|
+
// GC abandoned sims so `rnx list` stays usable across long dev / QA /
|
|
20737
20746
|
// test sessions (F21-3). conservative on purpose: a sim is only reaped
|
|
20738
20747
|
// when every "someone cares about this" signal is absent.
|
|
20739
20748
|
//
|
|
@@ -20749,7 +20758,7 @@ var init_bridge_host = __esm({
|
|
|
20749
20758
|
// using is the primary and/or holds a fresh user-active lease; one that is
|
|
20750
20759
|
// none of those and idle past the TTL is abandoned regardless of a stale
|
|
20751
20760
|
// focus flag.
|
|
20752
|
-
// automation sims are spawned by the playwright driver (`
|
|
20761
|
+
// automation sims are spawned by the playwright driver (`rnx open
|
|
20753
20762
|
// --driver playwright`, the factory/screenshot capture path), which tags them
|
|
20754
20763
|
// with `meta.sootsimHostDriver === 'playwright'` via the host's addInitScript.
|
|
20755
20764
|
// they are unattended one-shot browsers, never a human's tab, so they get a
|
|
@@ -21252,6 +21261,8 @@ var init_bridge_host = __esm({
|
|
|
21252
21261
|
return "evaluated page state";
|
|
21253
21262
|
case "screenshot":
|
|
21254
21263
|
return "captured screenshot";
|
|
21264
|
+
case "capture":
|
|
21265
|
+
return "captured app screen";
|
|
21255
21266
|
case "tap":
|
|
21256
21267
|
return "sent tap event";
|
|
21257
21268
|
case "keyboard":
|
|
@@ -21416,6 +21427,233 @@ var init_cli_constants = __esm({
|
|
|
21416
21427
|
}
|
|
21417
21428
|
});
|
|
21418
21429
|
|
|
21430
|
+
// src/cloud-contract.ts
|
|
21431
|
+
var RNX_CLOUD_MAX_ARTIFACT_BYTES;
|
|
21432
|
+
var init_cloud_contract = __esm({
|
|
21433
|
+
"src/cloud-contract.ts"() {
|
|
21434
|
+
"use strict";
|
|
21435
|
+
RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
|
|
21436
|
+
}
|
|
21437
|
+
});
|
|
21438
|
+
|
|
21439
|
+
// cli/cloud-session.ts
|
|
21440
|
+
function isRecord3(value) {
|
|
21441
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
21442
|
+
}
|
|
21443
|
+
function normalizeCloudOrigin(source) {
|
|
21444
|
+
let parsed;
|
|
21445
|
+
try {
|
|
21446
|
+
parsed = new URL(source);
|
|
21447
|
+
} catch {
|
|
21448
|
+
throw new Error(`invalid RNX Cloud origin: ${source}`);
|
|
21449
|
+
}
|
|
21450
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
21451
|
+
throw new Error(`RNX Cloud origin must be an HTTP(S) origin: ${source}`);
|
|
21452
|
+
}
|
|
21453
|
+
if (parsed.protocol === "http:" && !isLoopbackHost(parsed.hostname)) {
|
|
21454
|
+
throw new Error(`RNX Cloud origin requires HTTPS outside loopback: ${source}`);
|
|
21455
|
+
}
|
|
21456
|
+
return parsed.origin;
|
|
21457
|
+
}
|
|
21458
|
+
function createCloudSession(input) {
|
|
21459
|
+
const session = {
|
|
21460
|
+
version: CLOUD_SESSION_VERSION,
|
|
21461
|
+
simId: input.simId.trim(),
|
|
21462
|
+
apiOrigin: normalizeCloudOrigin(input.apiOrigin.trim()),
|
|
21463
|
+
claimId: input.claimId.trim(),
|
|
21464
|
+
token: input.token
|
|
21465
|
+
};
|
|
21466
|
+
if (!session.simId || !session.claimId || !session.token) {
|
|
21467
|
+
throw new Error("cloud session requires simulator, origin, claim, and token");
|
|
21468
|
+
}
|
|
21469
|
+
return session;
|
|
21470
|
+
}
|
|
21471
|
+
function parseCloudSession(encoded) {
|
|
21472
|
+
const value = encoded.trim();
|
|
21473
|
+
if (!value || value.length > MAX_ENCODED_SESSION_BYTES || !/^[A-Za-z0-9_-]+$/.test(value)) {
|
|
21474
|
+
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
21475
|
+
}
|
|
21476
|
+
let parsed;
|
|
21477
|
+
try {
|
|
21478
|
+
const bytes = Buffer.from(value, "base64url");
|
|
21479
|
+
if (bytes.toString("base64url") !== value) {
|
|
21480
|
+
throw new Error("non-canonical cloud session");
|
|
21481
|
+
}
|
|
21482
|
+
parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
21483
|
+
} catch {
|
|
21484
|
+
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
21485
|
+
}
|
|
21486
|
+
if (!isRecord3(parsed) || parsed.version !== CLOUD_SESSION_VERSION) {
|
|
21487
|
+
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
21488
|
+
}
|
|
21489
|
+
const simId = parsed.simId;
|
|
21490
|
+
const apiOrigin = parsed.apiOrigin;
|
|
21491
|
+
const claimId = parsed.claimId;
|
|
21492
|
+
const token = parsed.token;
|
|
21493
|
+
if (typeof simId !== "string" || typeof apiOrigin !== "string" || typeof claimId !== "string" || typeof token !== "string") {
|
|
21494
|
+
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
21495
|
+
}
|
|
21496
|
+
try {
|
|
21497
|
+
return createCloudSession({ simId, apiOrigin, claimId, token });
|
|
21498
|
+
} catch {
|
|
21499
|
+
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
21500
|
+
}
|
|
21501
|
+
}
|
|
21502
|
+
function readCloudSession(environment = process.env) {
|
|
21503
|
+
const encoded = environment[RNX_CLOUD_SESSION_ENV];
|
|
21504
|
+
return encoded?.trim() ? parseCloudSession(encoded) : null;
|
|
21505
|
+
}
|
|
21506
|
+
var CLOUD_SESSION_VERSION, MAX_ENCODED_SESSION_BYTES, RNX_CLOUD_SESSION_ENV, RNX_SHELL_UPDATE_PREFIX, RNX_SHELL_UPDATE_SET_PREFIX, RNX_SHELL_UPDATE_UNSET;
|
|
21507
|
+
var init_cloud_session = __esm({
|
|
21508
|
+
"cli/cloud-session.ts"() {
|
|
21509
|
+
"use strict";
|
|
21510
|
+
init_backend_origin();
|
|
21511
|
+
CLOUD_SESSION_VERSION = 1;
|
|
21512
|
+
MAX_ENCODED_SESSION_BYTES = 32 * 1024;
|
|
21513
|
+
RNX_CLOUD_SESSION_ENV = "RNX_CLOUD_SESSION";
|
|
21514
|
+
RNX_SHELL_UPDATE_PREFIX = "__RNX_SHELL_UPDATE_V1__";
|
|
21515
|
+
RNX_SHELL_UPDATE_SET_PREFIX = `${RNX_SHELL_UPDATE_PREFIX}set:`;
|
|
21516
|
+
RNX_SHELL_UPDATE_UNSET = `${RNX_SHELL_UPDATE_PREFIX}unset`;
|
|
21517
|
+
}
|
|
21518
|
+
});
|
|
21519
|
+
|
|
21520
|
+
// cli/cloud-client.ts
|
|
21521
|
+
function isRecord4(value) {
|
|
21522
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
21523
|
+
}
|
|
21524
|
+
function responseError(status, text) {
|
|
21525
|
+
if (text) {
|
|
21526
|
+
try {
|
|
21527
|
+
const parsed = JSON.parse(text);
|
|
21528
|
+
const error = isRecord4(parsed) ? parsed.error : null;
|
|
21529
|
+
if (isRecord4(error) && typeof error.message === "string") {
|
|
21530
|
+
return new Error(`RNX Cloud request failed (${status}): ${error.message}`);
|
|
21531
|
+
}
|
|
21532
|
+
} catch {
|
|
21533
|
+
}
|
|
21534
|
+
}
|
|
21535
|
+
return new Error(
|
|
21536
|
+
`RNX Cloud request failed (${status})${text.trim() ? `: ${text.trim()}` : ""}`
|
|
21537
|
+
);
|
|
21538
|
+
}
|
|
21539
|
+
function resolveCloudSessionForParsed(parsed) {
|
|
21540
|
+
const session = readCloudSession();
|
|
21541
|
+
if (!session) return null;
|
|
21542
|
+
if (parsed.simIdSource === "flag" && parsed.simId !== session.simId) {
|
|
21543
|
+
throw new Error(
|
|
21544
|
+
`this shell is connected to RNX Cloud simulator ${session.simId}; ${parsed.simId ? `--sim ${parsed.simId}` : "the requested simulator"} is not available in this shell`
|
|
21545
|
+
);
|
|
21546
|
+
}
|
|
21547
|
+
return session;
|
|
21548
|
+
}
|
|
21549
|
+
function cloudCommand(command) {
|
|
21550
|
+
const clean = {};
|
|
21551
|
+
for (const [key, value] of Object.entries(command)) {
|
|
21552
|
+
if (key !== "id" && key !== "simId") clean[key] = value;
|
|
21553
|
+
}
|
|
21554
|
+
if (command.type === "query") {
|
|
21555
|
+
const query = command.query;
|
|
21556
|
+
if (!isRecord4(query) || query.kind !== "tree" && query.kind !== "find" && query.kind !== "count") {
|
|
21557
|
+
throw new Error("RNX Cloud supports only structured tree, node, and count queries");
|
|
21558
|
+
}
|
|
21559
|
+
return clean;
|
|
21560
|
+
}
|
|
21561
|
+
if (command.type === "waitFor") {
|
|
21562
|
+
const options = command.waitForOptions;
|
|
21563
|
+
const condition = isRecord4(options) ? options.condition : null;
|
|
21564
|
+
if (!isRecord4(condition) || condition.type !== "ready" && condition.type !== "present" && condition.type !== "absent") {
|
|
21565
|
+
throw new Error("RNX Cloud supports only ready and selector waits");
|
|
21566
|
+
}
|
|
21567
|
+
return clean;
|
|
21568
|
+
}
|
|
21569
|
+
if (command.type === "state") return clean;
|
|
21570
|
+
if (command.type === "capture" || command.type === "captureRegions") return clean;
|
|
21571
|
+
if (command.type === "setAppearance" || command.type === "openUrl") return clean;
|
|
21572
|
+
if (command.type === "screenshot" && command.crop === void 0 && command.captureFilter === void 0 && (command.layers === void 0 || command.layers === "tenant")) {
|
|
21573
|
+
return clean;
|
|
21574
|
+
}
|
|
21575
|
+
throw new Error(`RNX Cloud does not support bridge command type ${command.type}`);
|
|
21576
|
+
}
|
|
21577
|
+
function createCloudBridgeForParsed(parsed) {
|
|
21578
|
+
const session = resolveCloudSessionForParsed(parsed);
|
|
21579
|
+
return session ? new CloudBridge(session) : null;
|
|
21580
|
+
}
|
|
21581
|
+
var import_node_crypto5, DEFAULT_RNX_CLOUD_ORIGIN, CloudBridge;
|
|
21582
|
+
var init_cloud_client = __esm({
|
|
21583
|
+
"cli/cloud-client.ts"() {
|
|
21584
|
+
"use strict";
|
|
21585
|
+
import_node_crypto5 = require("node:crypto");
|
|
21586
|
+
init_cloud_contract();
|
|
21587
|
+
init_public_brand();
|
|
21588
|
+
init_cloud_session();
|
|
21589
|
+
DEFAULT_RNX_CLOUD_ORIGIN = rnxPublicBrand.origin;
|
|
21590
|
+
CloudBridge = class {
|
|
21591
|
+
constructor(session) {
|
|
21592
|
+
this.session = session;
|
|
21593
|
+
}
|
|
21594
|
+
plane = "cloud";
|
|
21595
|
+
async send(command, options) {
|
|
21596
|
+
const body = {
|
|
21597
|
+
id: (0, import_node_crypto5.randomUUID)(),
|
|
21598
|
+
claimId: this.session.claimId,
|
|
21599
|
+
command: cloudCommand(command)
|
|
21600
|
+
};
|
|
21601
|
+
let response;
|
|
21602
|
+
try {
|
|
21603
|
+
response = await fetch(
|
|
21604
|
+
`${this.session.apiOrigin}/v1/sims/${encodeURIComponent(this.session.simId)}/commands`,
|
|
21605
|
+
{
|
|
21606
|
+
method: "POST",
|
|
21607
|
+
headers: {
|
|
21608
|
+
authorization: `Bearer ${this.session.token}`,
|
|
21609
|
+
"content-type": "application/json"
|
|
21610
|
+
},
|
|
21611
|
+
body: JSON.stringify(body),
|
|
21612
|
+
...options?.timeoutMs ? { signal: AbortSignal.timeout(options.timeoutMs) } : {}
|
|
21613
|
+
}
|
|
21614
|
+
);
|
|
21615
|
+
} catch (error) {
|
|
21616
|
+
throw new Error(
|
|
21617
|
+
`could not reach RNX Cloud at ${this.session.apiOrigin}: ${error instanceof Error ? error.message : String(error)}`
|
|
21618
|
+
);
|
|
21619
|
+
}
|
|
21620
|
+
const text = await response.text();
|
|
21621
|
+
if (!response.ok) throw responseError(response.status, text);
|
|
21622
|
+
let parsed;
|
|
21623
|
+
try {
|
|
21624
|
+
parsed = JSON.parse(text);
|
|
21625
|
+
} catch {
|
|
21626
|
+
throw new Error("RNX Cloud command returned unreadable JSON");
|
|
21627
|
+
}
|
|
21628
|
+
if (!isRecord4(parsed) || parsed.id !== body.id) {
|
|
21629
|
+
throw new Error("RNX Cloud command returned an invalid command receipt");
|
|
21630
|
+
}
|
|
21631
|
+
if (typeof parsed.error === "string" && parsed.error) throw new Error(parsed.error);
|
|
21632
|
+
if (!Object.hasOwn(parsed, "result")) {
|
|
21633
|
+
throw new Error("RNX Cloud command receipt has no result");
|
|
21634
|
+
}
|
|
21635
|
+
return parsed.result;
|
|
21636
|
+
}
|
|
21637
|
+
listSims() {
|
|
21638
|
+
return Promise.reject(new Error("RNX Cloud does not expose a local simulator list"));
|
|
21639
|
+
}
|
|
21640
|
+
focusSim() {
|
|
21641
|
+
return Promise.reject(
|
|
21642
|
+
new Error("RNX Cloud simulators have no browser window to focus")
|
|
21643
|
+
);
|
|
21644
|
+
}
|
|
21645
|
+
closeSim() {
|
|
21646
|
+
return Promise.reject(new Error("RNX Cloud close uses the simulator DELETE route"));
|
|
21647
|
+
}
|
|
21648
|
+
claim() {
|
|
21649
|
+
return Promise.reject(new Error("RNX Cloud claim uses the simulator claim route"));
|
|
21650
|
+
}
|
|
21651
|
+
close() {
|
|
21652
|
+
}
|
|
21653
|
+
};
|
|
21654
|
+
}
|
|
21655
|
+
});
|
|
21656
|
+
|
|
21419
21657
|
// cli/parent-pid.ts
|
|
21420
21658
|
function getParentPid(pid) {
|
|
21421
21659
|
if (!cached3) cached3 = build2();
|
|
@@ -21575,6 +21813,36 @@ var init_parent_pid = __esm({
|
|
|
21575
21813
|
}
|
|
21576
21814
|
});
|
|
21577
21815
|
|
|
21816
|
+
// cli/secure-file.ts
|
|
21817
|
+
function writeSecureJsonAtomic(filepath, value) {
|
|
21818
|
+
(0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(filepath), { recursive: true });
|
|
21819
|
+
const temporary = `${filepath}.tmp-${process.pid}-${(0, import_node_crypto6.randomUUID)()}`;
|
|
21820
|
+
let descriptor = null;
|
|
21821
|
+
try {
|
|
21822
|
+
descriptor = (0, import_node_fs12.openSync)(temporary, "wx", 384);
|
|
21823
|
+
(0, import_node_fs12.fchmodSync)(descriptor, 384);
|
|
21824
|
+
(0, import_node_fs12.writeFileSync)(descriptor, `${JSON.stringify(value, null, 2)}
|
|
21825
|
+
`);
|
|
21826
|
+
(0, import_node_fs12.fsyncSync)(descriptor);
|
|
21827
|
+
(0, import_node_fs12.closeSync)(descriptor);
|
|
21828
|
+
descriptor = null;
|
|
21829
|
+
(0, import_node_fs12.renameSync)(temporary, filepath);
|
|
21830
|
+
} catch (error) {
|
|
21831
|
+
if (descriptor !== null) (0, import_node_fs12.closeSync)(descriptor);
|
|
21832
|
+
(0, import_node_fs12.rmSync)(temporary, { force: true });
|
|
21833
|
+
throw error;
|
|
21834
|
+
}
|
|
21835
|
+
}
|
|
21836
|
+
var import_node_crypto6, import_node_fs12, import_node_path13;
|
|
21837
|
+
var init_secure_file = __esm({
|
|
21838
|
+
"cli/secure-file.ts"() {
|
|
21839
|
+
"use strict";
|
|
21840
|
+
import_node_crypto6 = require("node:crypto");
|
|
21841
|
+
import_node_fs12 = require("node:fs");
|
|
21842
|
+
import_node_path13 = require("node:path");
|
|
21843
|
+
}
|
|
21844
|
+
});
|
|
21845
|
+
|
|
21578
21846
|
// cli/current-sim.ts
|
|
21579
21847
|
function findTopAncestor(start, maxDepth = 20) {
|
|
21580
21848
|
let prev = start;
|
|
@@ -21621,50 +21889,57 @@ function getCurrentSimPath() {
|
|
|
21621
21889
|
const key = getCliIdentityKey();
|
|
21622
21890
|
return (0, import_path3.join)((0, import_os.tmpdir)(), `rnx-current-sim-${key}.json`);
|
|
21623
21891
|
}
|
|
21624
|
-
function
|
|
21892
|
+
function legacyCloudCredentialDirectory(filepath) {
|
|
21893
|
+
return (0, import_path3.join)((0, import_path3.dirname)(filepath), `${(0, import_path3.basename)(filepath)}.credentials`);
|
|
21894
|
+
}
|
|
21895
|
+
function readCurrentTarget() {
|
|
21625
21896
|
const filepath = getCurrentSimPath();
|
|
21897
|
+
(0, import_fs4.rmSync)(legacyCloudCredentialDirectory(filepath), { recursive: true, force: true });
|
|
21626
21898
|
if (!(0, import_fs4.existsSync)(filepath)) return null;
|
|
21627
21899
|
try {
|
|
21628
21900
|
const parsed = JSON.parse((0, import_fs4.readFileSync)(filepath, "utf8"));
|
|
21629
|
-
if (parsed
|
|
21901
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
21630
21902
|
(0, import_fs4.rmSync)(filepath, { force: true });
|
|
21631
21903
|
return null;
|
|
21632
21904
|
}
|
|
21633
|
-
|
|
21905
|
+
const version = Reflect.get(parsed, "version");
|
|
21906
|
+
const plane = Reflect.get(parsed, "plane");
|
|
21907
|
+
const simId = Reflect.get(parsed, "simId");
|
|
21908
|
+
const updatedAt = Reflect.get(parsed, "updatedAt");
|
|
21909
|
+
if (version !== 1 && version !== CURRENT_SIM_VERSION || version === CURRENT_SIM_VERSION && plane !== "local" || typeof simId !== "string" || !simId.trim() || typeof updatedAt !== "string") {
|
|
21910
|
+
(0, import_fs4.rmSync)(filepath, { force: true });
|
|
21911
|
+
return null;
|
|
21912
|
+
}
|
|
21913
|
+
const target = {
|
|
21634
21914
|
version: CURRENT_SIM_VERSION,
|
|
21635
|
-
|
|
21636
|
-
|
|
21915
|
+
plane: "local",
|
|
21916
|
+
simId: simId.trim(),
|
|
21917
|
+
updatedAt
|
|
21637
21918
|
};
|
|
21919
|
+
if (version === 1) writeSecureJsonAtomic(filepath, target);
|
|
21920
|
+
return target;
|
|
21638
21921
|
} catch {
|
|
21639
21922
|
(0, import_fs4.rmSync)(filepath, { force: true });
|
|
21640
21923
|
return null;
|
|
21641
21924
|
}
|
|
21642
21925
|
}
|
|
21643
21926
|
function readCurrentSimId() {
|
|
21644
|
-
return
|
|
21927
|
+
return readCurrentTarget()?.simId ?? null;
|
|
21645
21928
|
}
|
|
21646
21929
|
function saveCurrentSimId(simId) {
|
|
21647
21930
|
const normalized = simId.trim();
|
|
21648
21931
|
if (!normalized) return;
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
version: CURRENT_SIM_VERSION,
|
|
21656
|
-
simId: normalized,
|
|
21657
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
21658
|
-
},
|
|
21659
|
-
null,
|
|
21660
|
-
2
|
|
21661
|
-
) + "\n"
|
|
21662
|
-
);
|
|
21932
|
+
writeSecureJsonAtomic(getCurrentSimPath(), {
|
|
21933
|
+
version: CURRENT_SIM_VERSION,
|
|
21934
|
+
plane: "local",
|
|
21935
|
+
simId: normalized,
|
|
21936
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
21937
|
+
});
|
|
21663
21938
|
}
|
|
21664
21939
|
function clearCurrentSimId() {
|
|
21665
21940
|
(0, import_fs4.rmSync)(getCurrentSimPath(), { force: true });
|
|
21666
21941
|
}
|
|
21667
|
-
var import_fs4, import_os, import_path3, CURRENT_SIM_VERSION, CURRENT_SIM_PATH_ENV, IDENTITY_ENV_VARS, IMMORTAL_HOST_COMM_RE;
|
|
21942
|
+
var import_fs4, import_os, import_path3, CURRENT_SIM_VERSION, CURRENT_SIM_PATH_ENV, IDENTITY_ENV_VARS, IMMORTAL_HOST_COMM_RE, readCurrentSim;
|
|
21668
21943
|
var init_current_sim = __esm({
|
|
21669
21944
|
"cli/current-sim.ts"() {
|
|
21670
21945
|
"use strict";
|
|
@@ -21672,7 +21947,8 @@ var init_current_sim = __esm({
|
|
|
21672
21947
|
import_os = require("os");
|
|
21673
21948
|
import_path3 = require("path");
|
|
21674
21949
|
init_parent_pid();
|
|
21675
|
-
|
|
21950
|
+
init_secure_file();
|
|
21951
|
+
CURRENT_SIM_VERSION = 2;
|
|
21676
21952
|
CURRENT_SIM_PATH_ENV = "SOOTSIM_CLI_CURRENT_SIM_PATH";
|
|
21677
21953
|
IDENTITY_ENV_VARS = [
|
|
21678
21954
|
"RNX_CLI_IDENTITY",
|
|
@@ -21703,6 +21979,7 @@ var init_current_sim = __esm({
|
|
|
21703
21979
|
// vscode integrated terminal
|
|
21704
21980
|
];
|
|
21705
21981
|
IMMORTAL_HOST_COMM_RE = /^(?:tmux|screen)|^tm$/i;
|
|
21982
|
+
readCurrentSim = readCurrentTarget;
|
|
21706
21983
|
}
|
|
21707
21984
|
});
|
|
21708
21985
|
|
|
@@ -21736,17 +22013,17 @@ function liveDevBridgeLockfiles() {
|
|
|
21736
22013
|
return readDevBridgeLockfiles().filter((lockfile) => isDevBridgeLockfileFresh(lockfile));
|
|
21737
22014
|
}
|
|
21738
22015
|
function checkoutRoot(cwd) {
|
|
21739
|
-
let current =
|
|
22016
|
+
let current = import_node_path14.default.resolve(cwd);
|
|
21740
22017
|
while (true) {
|
|
21741
|
-
if (
|
|
21742
|
-
const parent =
|
|
22018
|
+
if (import_node_fs13.default.existsSync(import_node_path14.default.join(current, ".git"))) return current;
|
|
22019
|
+
const parent = import_node_path14.default.dirname(current);
|
|
21743
22020
|
if (parent === current) return null;
|
|
21744
22021
|
current = parent;
|
|
21745
22022
|
}
|
|
21746
22023
|
}
|
|
21747
22024
|
function pathContains(parent, child) {
|
|
21748
|
-
const relative =
|
|
21749
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
22025
|
+
const relative = import_node_path14.default.relative(parent, child);
|
|
22026
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${import_node_path14.default.sep}`) && !import_node_path14.default.isAbsolute(relative);
|
|
21750
22027
|
}
|
|
21751
22028
|
function resolveDefaultDevBridgeLockfile() {
|
|
21752
22029
|
const lockfiles = liveDevBridgeLockfiles();
|
|
@@ -21933,9 +22210,9 @@ function parseBridgeCliArgs(args, opts = {}) {
|
|
|
21933
22210
|
}
|
|
21934
22211
|
}
|
|
21935
22212
|
if (!simId) {
|
|
21936
|
-
const
|
|
21937
|
-
if (
|
|
21938
|
-
simId =
|
|
22213
|
+
const savedSim = readCurrentSim();
|
|
22214
|
+
if (savedSim) {
|
|
22215
|
+
simId = savedSim.simId.trim() || void 0;
|
|
21939
22216
|
simIdSource = "saved";
|
|
21940
22217
|
}
|
|
21941
22218
|
}
|
|
@@ -22031,6 +22308,7 @@ function createBridge(wsPort, opts = {}) {
|
|
|
22031
22308
|
}
|
|
22032
22309
|
});
|
|
22033
22310
|
return {
|
|
22311
|
+
plane: "local",
|
|
22034
22312
|
async send(cmd, callOpts) {
|
|
22035
22313
|
const effectiveTimeoutMs = callOpts?.timeoutMs ?? commandTimeoutMs;
|
|
22036
22314
|
const sendOnce = async (defaultSimId) => {
|
|
@@ -22113,6 +22391,8 @@ function createBridge(wsPort, opts = {}) {
|
|
|
22113
22391
|
};
|
|
22114
22392
|
}
|
|
22115
22393
|
function createBridgeFromParsed(parsed) {
|
|
22394
|
+
const cloudBridge = createCloudBridgeForParsed(parsed);
|
|
22395
|
+
if (cloudBridge) return cloudBridge;
|
|
22116
22396
|
return createBridge(parsed.wsPort, {
|
|
22117
22397
|
commandTimeoutMs: parsed.commandTimeoutMs,
|
|
22118
22398
|
simId: parsed.simId,
|
|
@@ -22175,16 +22455,17 @@ async function callInBridge(bridge, path20, ...args) {
|
|
|
22175
22455
|
async function callInBridgeWrite(bridge, path20, ...args) {
|
|
22176
22456
|
return bridge.send({ type: "call", path: path20, args, acquireLock: true });
|
|
22177
22457
|
}
|
|
22178
|
-
var
|
|
22458
|
+
var import_node_fs13, import_node_path14, import_ws3, RNX_PLACEMENT_ENV, resolvedWorld, BridgeSimLockedError;
|
|
22179
22459
|
var init_ws_bridge = __esm({
|
|
22180
22460
|
"cli/ws-bridge.ts"() {
|
|
22181
22461
|
"use strict";
|
|
22182
|
-
|
|
22183
|
-
|
|
22462
|
+
import_node_fs13 = __toESM(require("node:fs"), 1);
|
|
22463
|
+
import_node_path14 = __toESM(require("node:path"), 1);
|
|
22184
22464
|
import_ws3 = require("ws");
|
|
22185
22465
|
init_bridge_constants();
|
|
22186
22466
|
init_cli_constants();
|
|
22187
22467
|
init_home_paths();
|
|
22468
|
+
init_cloud_client();
|
|
22188
22469
|
init_current_sim();
|
|
22189
22470
|
RNX_PLACEMENT_ENV = "RNX_PLACEMENT";
|
|
22190
22471
|
resolvedWorld = null;
|
|
@@ -22220,9 +22501,8 @@ function isAppDeepLinkTarget(target) {
|
|
|
22220
22501
|
async function openAppUrl(bridge, target) {
|
|
22221
22502
|
const normalized = normalizeAppUrlTarget(target);
|
|
22222
22503
|
const result = await bridge.send({
|
|
22223
|
-
type: "
|
|
22224
|
-
|
|
22225
|
-
args: [normalized]
|
|
22504
|
+
type: "openUrl",
|
|
22505
|
+
url: normalized
|
|
22226
22506
|
});
|
|
22227
22507
|
if (result !== null && typeof result === "object" && Reflect.get(result, "ok") === false) {
|
|
22228
22508
|
const error = Reflect.get(result, "error");
|
|
@@ -22543,9 +22823,9 @@ var init_profiles = __esm({
|
|
|
22543
22823
|
// cli/app-project.ts
|
|
22544
22824
|
function firstNamedFile(dir, names) {
|
|
22545
22825
|
for (const name2 of names) {
|
|
22546
|
-
const candidate =
|
|
22826
|
+
const candidate = import_node_path15.default.join(dir, name2);
|
|
22547
22827
|
try {
|
|
22548
|
-
if (
|
|
22828
|
+
if (import_node_fs14.default.statSync(candidate).isFile()) return candidate;
|
|
22549
22829
|
} catch {
|
|
22550
22830
|
}
|
|
22551
22831
|
}
|
|
@@ -22558,24 +22838,24 @@ function findRNXAppConfig(dir) {
|
|
|
22558
22838
|
return firstNamedFile(dir, RNX_APP_CONFIG_NAMES);
|
|
22559
22839
|
}
|
|
22560
22840
|
function resolveAppProject(projectRoot) {
|
|
22561
|
-
const appDir =
|
|
22841
|
+
const appDir = import_node_path15.default.resolve(projectRoot);
|
|
22562
22842
|
try {
|
|
22563
|
-
if (!
|
|
22843
|
+
if (!import_node_fs14.default.statSync(appDir).isDirectory()) return null;
|
|
22564
22844
|
} catch {
|
|
22565
22845
|
return null;
|
|
22566
22846
|
}
|
|
22567
22847
|
const configPath = findRNXAppConfig(appDir);
|
|
22568
|
-
if (!configPath && !findExpoAppConfig(appDir) && !
|
|
22848
|
+
if (!configPath && !findExpoAppConfig(appDir) && !import_node_fs14.default.existsSync(import_node_path15.default.join(appDir, "package.json"))) {
|
|
22569
22849
|
return null;
|
|
22570
22850
|
}
|
|
22571
22851
|
return { appDir, configPath };
|
|
22572
22852
|
}
|
|
22573
|
-
var
|
|
22853
|
+
var import_node_fs14, import_node_path15, EXPO_APP_CONFIG_NAMES, RNX_APP_CONFIG_NAMES;
|
|
22574
22854
|
var init_app_project = __esm({
|
|
22575
22855
|
"cli/app-project.ts"() {
|
|
22576
22856
|
"use strict";
|
|
22577
|
-
|
|
22578
|
-
|
|
22857
|
+
import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
22858
|
+
import_node_path15 = __toESM(require("node:path"), 1);
|
|
22579
22859
|
EXPO_APP_CONFIG_NAMES = [
|
|
22580
22860
|
"app.config.js",
|
|
22581
22861
|
"app.config.ts",
|
|
@@ -22604,13 +22884,13 @@ function isRNXConfig(value) {
|
|
|
22604
22884
|
}
|
|
22605
22885
|
function resolveConfigReplacementFiles(config, configPath) {
|
|
22606
22886
|
if (!config.modules) return config;
|
|
22607
|
-
const configDir =
|
|
22887
|
+
const configDir = import_node_path16.default.dirname(configPath);
|
|
22608
22888
|
return {
|
|
22609
22889
|
...config,
|
|
22610
22890
|
modules: Object.fromEntries(
|
|
22611
22891
|
Object.entries(config.modules).map(([name2, resolution]) => [
|
|
22612
22892
|
name2,
|
|
22613
|
-
resolution && typeof resolution === "object" && "file" in resolution ? { ...resolution, file:
|
|
22893
|
+
resolution && typeof resolution === "object" && "file" in resolution ? { ...resolution, file: import_node_path16.default.resolve(configDir, resolution.file) } : resolution
|
|
22614
22894
|
])
|
|
22615
22895
|
)
|
|
22616
22896
|
};
|
|
@@ -22640,12 +22920,12 @@ async function resolveRNXAppConfig(startDir = process.cwd()) {
|
|
|
22640
22920
|
const project = resolveAppProject(startDir);
|
|
22641
22921
|
return { project, config: await loadRNXAppConfig(project) };
|
|
22642
22922
|
}
|
|
22643
|
-
var import_node_module,
|
|
22923
|
+
var import_node_module, import_node_path16, import_jiti, require2;
|
|
22644
22924
|
var init_app_config = __esm({
|
|
22645
22925
|
"cli/app-config.ts"() {
|
|
22646
22926
|
"use strict";
|
|
22647
22927
|
import_node_module = require("node:module");
|
|
22648
|
-
|
|
22928
|
+
import_node_path16 = __toESM(require("node:path"), 1);
|
|
22649
22929
|
init_src();
|
|
22650
22930
|
import_jiti = require("jiti");
|
|
22651
22931
|
init_public_brand();
|
|
@@ -22713,13 +22993,13 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
22713
22993
|
scannedFontDirectories++;
|
|
22714
22994
|
let entries;
|
|
22715
22995
|
try {
|
|
22716
|
-
entries =
|
|
22996
|
+
entries = import_node_fs15.default.readdirSync(current.dir, { withFileTypes: true });
|
|
22717
22997
|
} catch {
|
|
22718
22998
|
continue;
|
|
22719
22999
|
}
|
|
22720
23000
|
for (const entry of entries) {
|
|
22721
23001
|
if (entry.isSymbolicLink()) continue;
|
|
22722
|
-
const fullPath =
|
|
23002
|
+
const fullPath = import_node_path17.default.join(current.dir, entry.name);
|
|
22723
23003
|
if (entry.isDirectory()) {
|
|
22724
23004
|
if (current.depth < 4 && pending.length < 64 && !entry.name.startsWith(".")) {
|
|
22725
23005
|
pending.push({ dir: fullPath, depth: current.depth + 1 });
|
|
@@ -22727,15 +23007,15 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
22727
23007
|
continue;
|
|
22728
23008
|
}
|
|
22729
23009
|
if (!entry.isFile() || !/\.(ttf|otf|woff|woff2)$/i.test(entry.name)) continue;
|
|
22730
|
-
const relative =
|
|
22731
|
-
fontPaths.push(
|
|
23010
|
+
const relative = import_node_path17.default.relative(root, fullPath).split(import_node_path17.default.sep).join("/");
|
|
23011
|
+
fontPaths.push(import_node_path17.default.posix.join(metroPathPrefix, relative));
|
|
22732
23012
|
if (fontPaths.length >= 256) break;
|
|
22733
23013
|
}
|
|
22734
23014
|
}
|
|
22735
23015
|
};
|
|
22736
23016
|
try {
|
|
22737
23017
|
const packageJson = JSON.parse(
|
|
22738
|
-
|
|
23018
|
+
import_node_fs15.default.readFileSync(import_node_path17.default.join(selectedAppDir, "package.json"), "utf8")
|
|
22739
23019
|
);
|
|
22740
23020
|
const dependencyNames = /* @__PURE__ */ new Set();
|
|
22741
23021
|
for (const field of ["dependencies", "devDependencies", "optionalDependencies"]) {
|
|
@@ -22750,24 +23030,24 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
22750
23030
|
const config = Reflect.get(packageJson, "reactNativeVectorIcons");
|
|
22751
23031
|
const configuredFontDir = config && typeof config === "object" ? Reflect.get(config, "fontDir") : null;
|
|
22752
23032
|
const configuredDir = typeof configuredFontDir === "string" ? configuredFontDir : "rnvi-fonts";
|
|
22753
|
-
const root =
|
|
22754
|
-
const relativeRoot =
|
|
22755
|
-
if (!relativeRoot.startsWith("..") && !
|
|
22756
|
-
collectFontFiles(root, relativeRoot.split(
|
|
23033
|
+
const root = import_node_path17.default.resolve(selectedAppDir, configuredDir);
|
|
23034
|
+
const relativeRoot = import_node_path17.default.relative(selectedAppDir, root);
|
|
23035
|
+
if (!relativeRoot.startsWith("..") && !import_node_path17.default.isAbsolute(relativeRoot)) {
|
|
23036
|
+
collectFontFiles(root, relativeRoot.split(import_node_path17.default.sep).join("/"));
|
|
22757
23037
|
}
|
|
22758
|
-
const vectorIconRequire = (0, import_node_module2.createRequire)(
|
|
23038
|
+
const vectorIconRequire = (0, import_node_module2.createRequire)(import_node_path17.default.join(selectedAppDir, "package.json"));
|
|
22759
23039
|
for (const dependencyName of vectorIconDependencies) {
|
|
22760
23040
|
try {
|
|
22761
23041
|
const entryPath = vectorIconRequire.resolve(dependencyName);
|
|
22762
|
-
const dependencyPath = dependencyName.split("/").join(
|
|
22763
|
-
const marker = `${
|
|
23042
|
+
const dependencyPath = dependencyName.split("/").join(import_node_path17.default.sep);
|
|
23043
|
+
const marker = `${import_node_path17.default.sep}node_modules${import_node_path17.default.sep}${dependencyPath}${import_node_path17.default.sep}`;
|
|
22764
23044
|
const markerIndex = entryPath.lastIndexOf(marker);
|
|
22765
23045
|
if (markerIndex === -1) continue;
|
|
22766
23046
|
const packageRoot = entryPath.slice(0, markerIndex + marker.length - 1);
|
|
22767
23047
|
const fontsDir = dependencyName === "react-native-vector-icons" ? "Fonts" : "fonts";
|
|
22768
23048
|
collectFontFiles(
|
|
22769
|
-
|
|
22770
|
-
|
|
23049
|
+
import_node_path17.default.join(packageRoot, fontsDir),
|
|
23050
|
+
import_node_path17.default.posix.join("node_modules", dependencyName, fontsDir)
|
|
22771
23051
|
);
|
|
22772
23052
|
} catch {
|
|
22773
23053
|
}
|
|
@@ -22776,37 +23056,37 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
22776
23056
|
} catch {
|
|
22777
23057
|
}
|
|
22778
23058
|
try {
|
|
22779
|
-
const configPath =
|
|
22780
|
-
if (
|
|
22781
|
-
const appConfigRequire = (0, import_node_module2.createRequire)(
|
|
23059
|
+
const configPath = import_node_path17.default.join(selectedAppDir, "react-native.config.js");
|
|
23060
|
+
if (import_node_fs15.default.statSync(configPath).isFile()) {
|
|
23061
|
+
const appConfigRequire = (0, import_node_module2.createRequire)(import_node_path17.default.join(selectedAppDir, "package.json"));
|
|
22782
23062
|
const rnConfig = appConfigRequire(configPath);
|
|
22783
23063
|
const assets = rnConfig && typeof rnConfig === "object" ? Reflect.get(rnConfig, "assets") : null;
|
|
22784
23064
|
if (Array.isArray(assets)) {
|
|
22785
23065
|
for (const assetDir of assets) {
|
|
22786
23066
|
if (typeof assetDir !== "string") continue;
|
|
22787
|
-
const root =
|
|
22788
|
-
const relativeRoot =
|
|
22789
|
-
if (relativeRoot.startsWith("..") ||
|
|
22790
|
-
collectFontFiles(root, relativeRoot.split(
|
|
23067
|
+
const root = import_node_path17.default.resolve(selectedAppDir, assetDir);
|
|
23068
|
+
const relativeRoot = import_node_path17.default.relative(selectedAppDir, root);
|
|
23069
|
+
if (relativeRoot.startsWith("..") || import_node_path17.default.isAbsolute(relativeRoot)) continue;
|
|
23070
|
+
collectFontFiles(root, relativeRoot.split(import_node_path17.default.sep).join("/"));
|
|
22791
23071
|
}
|
|
22792
23072
|
}
|
|
22793
23073
|
}
|
|
22794
23074
|
} catch {
|
|
22795
23075
|
}
|
|
22796
23076
|
if (platform === "ios") {
|
|
22797
|
-
const iosDir =
|
|
23077
|
+
const iosDir = import_node_path17.default.join(selectedAppDir, "ios");
|
|
22798
23078
|
try {
|
|
22799
|
-
const targetDirs =
|
|
23079
|
+
const targetDirs = import_node_fs15.default.readdirSync(iosDir, { withFileTypes: true }).filter(
|
|
22800
23080
|
(entry) => entry.isDirectory() && !entry.isSymbolicLink() && entry.name !== "Pods" && entry.name !== "build" && !entry.name.startsWith(".")
|
|
22801
23081
|
).slice(0, 64);
|
|
22802
|
-
const plistPaths = [
|
|
23082
|
+
const plistPaths = [import_node_path17.default.join(iosDir, "Info.plist")];
|
|
22803
23083
|
for (const entry of targetDirs) {
|
|
22804
|
-
plistPaths.push(
|
|
23084
|
+
plistPaths.push(import_node_path17.default.join(iosDir, entry.name, "Info.plist"));
|
|
22805
23085
|
}
|
|
22806
23086
|
for (const plistPath of plistPaths) {
|
|
22807
23087
|
let parsed;
|
|
22808
23088
|
try {
|
|
22809
|
-
parsed = parsePlistSource(
|
|
23089
|
+
parsed = parsePlistSource(import_node_fs15.default.readFileSync(plistPath, "utf8"));
|
|
22810
23090
|
} catch {
|
|
22811
23091
|
continue;
|
|
22812
23092
|
}
|
|
@@ -22816,21 +23096,21 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
22816
23096
|
for (const declaredFont of declaredFonts) {
|
|
22817
23097
|
if (typeof declaredFont !== "string") continue;
|
|
22818
23098
|
const candidates = [
|
|
22819
|
-
|
|
22820
|
-
|
|
23099
|
+
import_node_path17.default.resolve(import_node_path17.default.dirname(plistPath), declaredFont),
|
|
23100
|
+
import_node_path17.default.resolve(iosDir, declaredFont)
|
|
22821
23101
|
];
|
|
22822
23102
|
const fontPath = candidates.find((candidate) => {
|
|
22823
|
-
const relative =
|
|
22824
|
-
if (relative.startsWith("..") ||
|
|
23103
|
+
const relative = import_node_path17.default.relative(selectedAppDir, candidate);
|
|
23104
|
+
if (relative.startsWith("..") || import_node_path17.default.isAbsolute(relative)) return false;
|
|
22825
23105
|
try {
|
|
22826
|
-
return
|
|
23106
|
+
return import_node_fs15.default.statSync(candidate).isFile();
|
|
22827
23107
|
} catch {
|
|
22828
23108
|
return false;
|
|
22829
23109
|
}
|
|
22830
23110
|
});
|
|
22831
23111
|
if (!fontPath) continue;
|
|
22832
23112
|
fontPaths.push(
|
|
22833
|
-
|
|
23113
|
+
import_node_path17.default.relative(selectedAppDir, fontPath).split(import_node_path17.default.sep).join("/")
|
|
22834
23114
|
);
|
|
22835
23115
|
}
|
|
22836
23116
|
}
|
|
@@ -22869,13 +23149,13 @@ async function resolveMetroProjectRoot(bundleUrl, opts) {
|
|
|
22869
23149
|
function encodeAppFontsWire(specs) {
|
|
22870
23150
|
return specs.map((spec) => `${encodeURIComponent(spec.url)}::${encodeURIComponent(spec.family)}`).join(",");
|
|
22871
23151
|
}
|
|
22872
|
-
var
|
|
23152
|
+
var import_node_fs15, import_node_module2, import_node_path17, import_config_plugin_fonts, require3;
|
|
22873
23153
|
var init_app_fonts = __esm({
|
|
22874
23154
|
"cli/app-fonts.ts"() {
|
|
22875
23155
|
"use strict";
|
|
22876
|
-
|
|
23156
|
+
import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
22877
23157
|
import_node_module2 = require("node:module");
|
|
22878
|
-
|
|
23158
|
+
import_node_path17 = __toESM(require("node:path"), 1);
|
|
22879
23159
|
import_config_plugin_fonts = require("sootsim-engine/engine/config-plugin-fonts");
|
|
22880
23160
|
init_dev_server_scanner();
|
|
22881
23161
|
init_plist();
|
|
@@ -23953,7 +24233,7 @@ var init_browser_cache = __esm({
|
|
|
23953
24233
|
});
|
|
23954
24234
|
|
|
23955
24235
|
// cli/drivers/playwright-provisioning.ts
|
|
23956
|
-
function
|
|
24236
|
+
function isRecord5(value) {
|
|
23957
24237
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23958
24238
|
}
|
|
23959
24239
|
function resolvePlaywright() {
|
|
@@ -23966,20 +24246,20 @@ function resolvePlaywright() {
|
|
|
23966
24246
|
try {
|
|
23967
24247
|
const modulePath = requireFromRoot.resolve(spec);
|
|
23968
24248
|
const packageJsonPath = requireFromRoot.resolve(`${spec}/package.json`);
|
|
23969
|
-
const parsed = JSON.parse((0,
|
|
23970
|
-
if (!
|
|
24249
|
+
const parsed = JSON.parse((0, import_node_fs16.readFileSync)(packageJsonPath, "utf8"));
|
|
24250
|
+
if (!isRecord5(parsed) || typeof parsed.version !== "string") continue;
|
|
23971
24251
|
const bin = parsed.bin;
|
|
23972
24252
|
let binPath = null;
|
|
23973
24253
|
if (typeof bin === "string") {
|
|
23974
24254
|
binPath = bin;
|
|
23975
|
-
} else if (
|
|
24255
|
+
} else if (isRecord5(bin)) {
|
|
23976
24256
|
const named = bin.playwright ?? bin["playwright-core"];
|
|
23977
24257
|
const first = Object.values(bin).find((value) => typeof value === "string");
|
|
23978
24258
|
binPath = typeof named === "string" ? named : typeof first === "string" ? first : null;
|
|
23979
24259
|
}
|
|
23980
24260
|
if (!binPath) continue;
|
|
23981
|
-
const cliPath = (0,
|
|
23982
|
-
if (!(0,
|
|
24261
|
+
const cliPath = (0, import_node_path18.join)((0, import_node_path18.dirname)(packageJsonPath), binPath);
|
|
24262
|
+
if (!(0, import_node_fs16.existsSync)(cliPath)) continue;
|
|
23983
24263
|
return {
|
|
23984
24264
|
spec,
|
|
23985
24265
|
modulePath,
|
|
@@ -24012,13 +24292,13 @@ function probeBrowser(resolved, env) {
|
|
|
24012
24292
|
}
|
|
24013
24293
|
try {
|
|
24014
24294
|
const parsed = JSON.parse(probe3.stdout);
|
|
24015
|
-
if (!
|
|
24295
|
+
if (!isRecord5(parsed) || typeof parsed.executablePath !== "string" || typeof parsed.exists !== "boolean") {
|
|
24016
24296
|
throw new Error("probe returned an invalid result");
|
|
24017
24297
|
}
|
|
24018
24298
|
return {
|
|
24019
24299
|
ok: true,
|
|
24020
24300
|
executablePath: parsed.executablePath,
|
|
24021
|
-
exists: parsed.exists && (0,
|
|
24301
|
+
exists: parsed.exists && (0, import_node_fs16.existsSync)(parsed.executablePath)
|
|
24022
24302
|
};
|
|
24023
24303
|
} catch (error) {
|
|
24024
24304
|
return {
|
|
@@ -24057,14 +24337,14 @@ ${detail}` : ""}`
|
|
|
24057
24337
|
}
|
|
24058
24338
|
return { ok: true, executablePath: after.executablePath, installed: true };
|
|
24059
24339
|
}
|
|
24060
|
-
var import_node_child_process6,
|
|
24340
|
+
var import_node_child_process6, import_node_fs16, import_node_module4, import_node_path18, PLAYWRIGHT_BROWSER_PROBE;
|
|
24061
24341
|
var init_playwright_provisioning = __esm({
|
|
24062
24342
|
"cli/drivers/playwright-provisioning.ts"() {
|
|
24063
24343
|
"use strict";
|
|
24064
24344
|
import_node_child_process6 = require("node:child_process");
|
|
24065
|
-
|
|
24345
|
+
import_node_fs16 = require("node:fs");
|
|
24066
24346
|
import_node_module4 = require("node:module");
|
|
24067
|
-
|
|
24347
|
+
import_node_path18 = require("node:path");
|
|
24068
24348
|
PLAYWRIGHT_BROWSER_PROBE = `
|
|
24069
24349
|
const { existsSync } = require('node:fs');
|
|
24070
24350
|
const modulePath = process.env.SOOTSIM_PW_MODULE;
|
|
@@ -24474,7 +24754,7 @@ const cleanupProfile = () => {
|
|
|
24474
24754
|
// we are spawned detached + unref'd so \`rnx open\` returns immediately,
|
|
24475
24755
|
// which means nothing in the OS process tree ties Chrome's lifetime to the
|
|
24476
24756
|
// session that asked for it. once the sim connects, the connect-timeout
|
|
24477
|
-
// safety net is cleared, so absent an explicit \`
|
|
24757
|
+
// safety net is cleared, so absent an explicit \`rnx close\` (or the
|
|
24478
24758
|
// daemon's idle reaper closing the sim socket) the host would hold Chrome
|
|
24479
24759
|
// open forever after its owner exits. poll the owning session's pid and tear
|
|
24480
24760
|
// down when it's gone. ESRCH (kill throws) = owner exited; EPERM = alive but
|
|
@@ -24765,10 +25045,10 @@ var init_run_rnx = __esm({
|
|
|
24765
25045
|
});
|
|
24766
25046
|
|
|
24767
25047
|
// cli/commands/inspect/env.ts
|
|
24768
|
-
function isAgentEnv() {
|
|
24769
|
-
if (
|
|
25048
|
+
function isAgentEnv(env = process.env) {
|
|
25049
|
+
if (env.RNX_AGENT === "0") return false;
|
|
24770
25050
|
for (const name2 of AGENT_ENV_VARS) {
|
|
24771
|
-
const v =
|
|
25051
|
+
const v = env[name2];
|
|
24772
25052
|
if (v && v.trim() && v !== "0") return true;
|
|
24773
25053
|
}
|
|
24774
25054
|
return false;
|
|
@@ -24933,7 +25213,7 @@ async function activateVersion(version) {
|
|
|
24933
25213
|
const notified = await tellDaemonRuntimeChanged(version);
|
|
24934
25214
|
if (!notified) {
|
|
24935
25215
|
console.log(
|
|
24936
|
-
` (no daemon running \u2014 next
|
|
25216
|
+
` (no daemon running \u2014 next rnx/electron launch will pick up ${version})`
|
|
24937
25217
|
);
|
|
24938
25218
|
}
|
|
24939
25219
|
}
|
|
@@ -25240,14 +25520,14 @@ function assertExplicitBridgeLock(preferredPort, explicitPort, lock) {
|
|
|
25240
25520
|
}
|
|
25241
25521
|
async function ensureRuntimeForOpen() {
|
|
25242
25522
|
const active = readActiveRuntime();
|
|
25243
|
-
if (active &&
|
|
25523
|
+
if (active && import_node_fs17.default.existsSync(runtimeDir(active))) return;
|
|
25244
25524
|
console.error(" installing rnx engine runtime...");
|
|
25245
25525
|
const { runRuntime: runRuntime2 } = await Promise.resolve().then(() => (init_runtime(), runtime_exports));
|
|
25246
25526
|
await runRuntime2(["install"], {});
|
|
25247
25527
|
}
|
|
25248
25528
|
function spawnSootsim(args) {
|
|
25249
25529
|
const entry = process.argv[1];
|
|
25250
|
-
if (entry &&
|
|
25530
|
+
if (entry && import_node_fs17.default.existsSync(entry)) {
|
|
25251
25531
|
return (0, import_node_child_process7.spawn)(process.execPath, [entry, ...args], {
|
|
25252
25532
|
detached: true,
|
|
25253
25533
|
stdio: "ignore",
|
|
@@ -25394,10 +25674,10 @@ async function buildResolvedBundleOpenUrl(target, baseUrl, opts = {}) {
|
|
|
25394
25674
|
}
|
|
25395
25675
|
function normalizeReplacementPath(filePath) {
|
|
25396
25676
|
if (filePath.startsWith("~/")) {
|
|
25397
|
-
return
|
|
25677
|
+
return import_node_path19.default.join(import_node_os3.default.homedir(), filePath.slice(2));
|
|
25398
25678
|
}
|
|
25399
|
-
if (
|
|
25400
|
-
return
|
|
25679
|
+
if (import_node_path19.default.isAbsolute(filePath)) return filePath;
|
|
25680
|
+
return import_node_path19.default.resolve(process.cwd(), filePath);
|
|
25401
25681
|
}
|
|
25402
25682
|
function parseOpenRuntimeConfig(args) {
|
|
25403
25683
|
const modules = {};
|
|
@@ -25416,7 +25696,7 @@ function parseOpenRuntimeConfig(args) {
|
|
|
25416
25696
|
}
|
|
25417
25697
|
const moduleName = raw.slice(0, eqIndex).trim();
|
|
25418
25698
|
const filePath = normalizeReplacementPath(raw.slice(eqIndex + 1).trim());
|
|
25419
|
-
if (!
|
|
25699
|
+
if (!import_node_fs17.default.existsSync(filePath)) {
|
|
25420
25700
|
console.error(` rnx open: replacement file not found: ${filePath}`);
|
|
25421
25701
|
rnxExit(1);
|
|
25422
25702
|
}
|
|
@@ -25447,7 +25727,7 @@ async function resolveOpenAppProject(resolvedBundle) {
|
|
|
25447
25727
|
return advertisedRoot ? resolveAppProject(advertisedRoot) : null;
|
|
25448
25728
|
}
|
|
25449
25729
|
async function ensureConfiguredRuntime(version) {
|
|
25450
|
-
if (
|
|
25730
|
+
if (import_node_fs17.default.existsSync(import_node_path19.default.join(runtimeDir(version), "index.html"))) return;
|
|
25451
25731
|
console.error(` installing configured engine runtime ${version}...`);
|
|
25452
25732
|
const result = await rnxRuntime.install({
|
|
25453
25733
|
version,
|
|
@@ -25807,7 +26087,7 @@ function playwrightHostPidForSim(sim) {
|
|
|
25807
26087
|
function signalDriverLaunchConnected(result) {
|
|
25808
26088
|
if (!result.connectAckFile) return false;
|
|
25809
26089
|
try {
|
|
25810
|
-
|
|
26090
|
+
import_node_fs17.default.writeFileSync(
|
|
25811
26091
|
result.connectAckFile,
|
|
25812
26092
|
`${JSON.stringify({ connectedAt: Date.now(), pid: result.pid ?? null })}
|
|
25813
26093
|
`,
|
|
@@ -25821,19 +26101,19 @@ function signalDriverLaunchConnected(result) {
|
|
|
25821
26101
|
function printDriverDiagnosticLogTail(result) {
|
|
25822
26102
|
if (!result.diagnosticLogPath) return;
|
|
25823
26103
|
try {
|
|
25824
|
-
const detail =
|
|
26104
|
+
const detail = import_node_fs17.default.readFileSync(result.diagnosticLogPath, "utf8").trim();
|
|
25825
26105
|
if (!detail) {
|
|
25826
|
-
console.error(` ${
|
|
26106
|
+
console.error(` ${import_node_path19.default.basename(result.diagnosticLogPath)} was empty`);
|
|
25827
26107
|
return;
|
|
25828
26108
|
}
|
|
25829
26109
|
const shown = detail.length > 4e3 ? `\u2026
|
|
25830
26110
|
${detail.slice(-4e3)}` : detail;
|
|
25831
|
-
console.error(` ${
|
|
26111
|
+
console.error(` ${import_node_path19.default.basename(result.diagnosticLogPath)}:`);
|
|
25832
26112
|
console.error(shown);
|
|
25833
26113
|
} catch (err) {
|
|
25834
26114
|
const message = err instanceof Error ? err.message : String(err);
|
|
25835
26115
|
console.error(
|
|
25836
|
-
` failed to read ${
|
|
26116
|
+
` failed to read ${import_node_path19.default.basename(result.diagnosticLogPath)}: ${message}`
|
|
25837
26117
|
);
|
|
25838
26118
|
}
|
|
25839
26119
|
}
|
|
@@ -26644,14 +26924,14 @@ async function runCloseCommand(args, opts = {}) {
|
|
|
26644
26924
|
bridge.close();
|
|
26645
26925
|
}
|
|
26646
26926
|
}
|
|
26647
|
-
var import_node_child_process7,
|
|
26927
|
+
var import_node_child_process7, import_node_fs17, import_node_os3, import_node_path19, import_settings, import_ws5, DEFAULT_DRIVER_CONNECT_TIMEOUT_MS, DRIVER_CONNECT_INTERVAL_MS, DRIVER_CONNECT_HOST_GRACE_MS, OPEN_BRIDGE_SPAWN_TIMEOUT_MS, SHELL_APPS;
|
|
26648
26928
|
var init_control = __esm({
|
|
26649
26929
|
"cli/commands/control.ts"() {
|
|
26650
26930
|
"use strict";
|
|
26651
26931
|
import_node_child_process7 = require("node:child_process");
|
|
26652
|
-
|
|
26932
|
+
import_node_fs17 = __toESM(require("node:fs"), 1);
|
|
26653
26933
|
import_node_os3 = __toESM(require("node:os"), 1);
|
|
26654
|
-
|
|
26934
|
+
import_node_path19 = __toESM(require("node:path"), 1);
|
|
26655
26935
|
import_settings = require("sootsim-engine/settings");
|
|
26656
26936
|
import_ws5 = require("ws");
|
|
26657
26937
|
init_dev_server_scanner();
|
|
@@ -27515,14 +27795,14 @@ process.stdin.on('end', async () => {
|
|
|
27515
27795
|
function getBaseDir() {
|
|
27516
27796
|
const explicit = process.env[SESSION_FILE_ENV];
|
|
27517
27797
|
if (explicit?.trim()) {
|
|
27518
|
-
return (0,
|
|
27798
|
+
return (0, import_node_path20.dirname)((0, import_node_path20.resolve)(explicit));
|
|
27519
27799
|
}
|
|
27520
27800
|
return electronUserDataDir();
|
|
27521
27801
|
}
|
|
27522
27802
|
function getSharedDesktopAuthFilePath() {
|
|
27523
27803
|
const explicit = process.env[SESSION_FILE_ENV];
|
|
27524
|
-
if (explicit?.trim()) return (0,
|
|
27525
|
-
return (0,
|
|
27804
|
+
if (explicit?.trim()) return (0, import_node_path20.resolve)(explicit);
|
|
27805
|
+
return (0, import_node_path20.join)(getBaseDir(), "desktop-auth.json");
|
|
27526
27806
|
}
|
|
27527
27807
|
function normalizeUser(input) {
|
|
27528
27808
|
if (!input || typeof input !== "object") return null;
|
|
@@ -27569,26 +27849,26 @@ function normalizeSession(input) {
|
|
|
27569
27849
|
}
|
|
27570
27850
|
function readSharedDesktopAuthSession() {
|
|
27571
27851
|
const filepath = getSharedDesktopAuthFilePath();
|
|
27572
|
-
if (!(0,
|
|
27852
|
+
if (!(0, import_node_fs18.existsSync)(filepath)) return null;
|
|
27573
27853
|
try {
|
|
27574
|
-
const parsed = JSON.parse((0,
|
|
27854
|
+
const parsed = JSON.parse((0, import_node_fs18.readFileSync)(filepath, "utf8"));
|
|
27575
27855
|
const normalized = normalizeSession(parsed);
|
|
27576
27856
|
if (!normalized) {
|
|
27577
|
-
(0,
|
|
27857
|
+
(0, import_node_fs18.rmSync)(filepath, { force: true });
|
|
27578
27858
|
return null;
|
|
27579
27859
|
}
|
|
27580
27860
|
return normalized;
|
|
27581
27861
|
} catch {
|
|
27582
|
-
(0,
|
|
27862
|
+
(0, import_node_fs18.rmSync)(filepath, { force: true });
|
|
27583
27863
|
return null;
|
|
27584
27864
|
}
|
|
27585
27865
|
}
|
|
27586
|
-
var
|
|
27866
|
+
var import_node_fs18, import_node_path20, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
|
|
27587
27867
|
var init_shared_session = __esm({
|
|
27588
27868
|
"src/auth/shared-session.ts"() {
|
|
27589
27869
|
"use strict";
|
|
27590
|
-
|
|
27591
|
-
|
|
27870
|
+
import_node_fs18 = require("node:fs");
|
|
27871
|
+
import_node_path20 = require("node:path");
|
|
27592
27872
|
init_home_paths();
|
|
27593
27873
|
SESSION_VERSION = 1;
|
|
27594
27874
|
SESSION_FILE_ENV = "SOOTSIM_SHARED_AUTH_FILE";
|
|
@@ -29176,7 +29456,7 @@ var init_bridge_flow_runner = __esm({
|
|
|
29176
29456
|
await this.resetGuestAppData();
|
|
29177
29457
|
await this.rearmCaptureAfterRuntimeReload();
|
|
29178
29458
|
}
|
|
29179
|
-
// maestro clearKeychain: there is no real keychain in
|
|
29459
|
+
// maestro clearKeychain: there is no real keychain in rnx's browser
|
|
29180
29460
|
// sandbox. log loudly so the author notices, then continue — matching the
|
|
29181
29461
|
// "loud warning, not silent skip" policy in the plan.
|
|
29182
29462
|
clearKeychain() {
|