rnxsim 0.1.381 → 0.1.383
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 +20 -8
- package/dist-lib/bridge-contract-input.mjs +20 -8
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +217 -0
- package/dist-lib/capture-contract.mjs +187 -0
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +41 -0
- package/dist-lib/cloud-contract.mjs +13 -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 +361 -75
- 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 +436 -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 +25 -6
- package/src/bridge-contract.ts +35 -5
- package/src/capture-contract.ts +576 -0
- package/src/cloud-contract.ts +18 -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 +25 -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.383 | (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,234 @@ var init_cli_constants = __esm({
|
|
|
21416
21427
|
}
|
|
21417
21428
|
});
|
|
21418
21429
|
|
|
21430
|
+
// src/cloud-contract.ts
|
|
21431
|
+
var RNX_CLOUD_MAX_ARTIFACT_BYTES, RNX_CLOUD_DESIGN_MAX_STORAGE_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
|
+
RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
|
|
21437
|
+
}
|
|
21438
|
+
});
|
|
21439
|
+
|
|
21440
|
+
// cli/cloud-session.ts
|
|
21441
|
+
function isRecord3(value) {
|
|
21442
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
21443
|
+
}
|
|
21444
|
+
function normalizeCloudOrigin(source) {
|
|
21445
|
+
let parsed;
|
|
21446
|
+
try {
|
|
21447
|
+
parsed = new URL(source);
|
|
21448
|
+
} catch {
|
|
21449
|
+
throw new Error(`invalid RNX Cloud origin: ${source}`);
|
|
21450
|
+
}
|
|
21451
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
21452
|
+
throw new Error(`RNX Cloud origin must be an HTTP(S) origin: ${source}`);
|
|
21453
|
+
}
|
|
21454
|
+
if (parsed.protocol === "http:" && !isLoopbackHost(parsed.hostname)) {
|
|
21455
|
+
throw new Error(`RNX Cloud origin requires HTTPS outside loopback: ${source}`);
|
|
21456
|
+
}
|
|
21457
|
+
return parsed.origin;
|
|
21458
|
+
}
|
|
21459
|
+
function createCloudSession(input) {
|
|
21460
|
+
const session = {
|
|
21461
|
+
version: CLOUD_SESSION_VERSION,
|
|
21462
|
+
simId: input.simId.trim(),
|
|
21463
|
+
apiOrigin: normalizeCloudOrigin(input.apiOrigin.trim()),
|
|
21464
|
+
claimId: input.claimId.trim(),
|
|
21465
|
+
token: input.token
|
|
21466
|
+
};
|
|
21467
|
+
if (!session.simId || !session.claimId || !session.token) {
|
|
21468
|
+
throw new Error("cloud session requires simulator, origin, claim, and token");
|
|
21469
|
+
}
|
|
21470
|
+
return session;
|
|
21471
|
+
}
|
|
21472
|
+
function parseCloudSession(encoded) {
|
|
21473
|
+
const value = encoded.trim();
|
|
21474
|
+
if (!value || value.length > MAX_ENCODED_SESSION_BYTES || !/^[A-Za-z0-9_-]+$/.test(value)) {
|
|
21475
|
+
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
21476
|
+
}
|
|
21477
|
+
let parsed;
|
|
21478
|
+
try {
|
|
21479
|
+
const bytes = Buffer.from(value, "base64url");
|
|
21480
|
+
if (bytes.toString("base64url") !== value) {
|
|
21481
|
+
throw new Error("non-canonical cloud session");
|
|
21482
|
+
}
|
|
21483
|
+
parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
21484
|
+
} catch {
|
|
21485
|
+
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
21486
|
+
}
|
|
21487
|
+
if (!isRecord3(parsed) || parsed.version !== CLOUD_SESSION_VERSION) {
|
|
21488
|
+
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
21489
|
+
}
|
|
21490
|
+
const simId = parsed.simId;
|
|
21491
|
+
const apiOrigin = parsed.apiOrigin;
|
|
21492
|
+
const claimId = parsed.claimId;
|
|
21493
|
+
const token = parsed.token;
|
|
21494
|
+
if (typeof simId !== "string" || typeof apiOrigin !== "string" || typeof claimId !== "string" || typeof token !== "string") {
|
|
21495
|
+
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
21496
|
+
}
|
|
21497
|
+
try {
|
|
21498
|
+
return createCloudSession({ simId, apiOrigin, claimId, token });
|
|
21499
|
+
} catch {
|
|
21500
|
+
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
21501
|
+
}
|
|
21502
|
+
}
|
|
21503
|
+
function readCloudSession(environment = process.env) {
|
|
21504
|
+
const encoded = environment[RNX_CLOUD_SESSION_ENV];
|
|
21505
|
+
return encoded?.trim() ? parseCloudSession(encoded) : null;
|
|
21506
|
+
}
|
|
21507
|
+
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;
|
|
21508
|
+
var init_cloud_session = __esm({
|
|
21509
|
+
"cli/cloud-session.ts"() {
|
|
21510
|
+
"use strict";
|
|
21511
|
+
init_backend_origin();
|
|
21512
|
+
CLOUD_SESSION_VERSION = 1;
|
|
21513
|
+
MAX_ENCODED_SESSION_BYTES = 32 * 1024;
|
|
21514
|
+
RNX_CLOUD_SESSION_ENV = "RNX_CLOUD_SESSION";
|
|
21515
|
+
RNX_SHELL_UPDATE_PREFIX = "__RNX_SHELL_UPDATE_V1__";
|
|
21516
|
+
RNX_SHELL_UPDATE_SET_PREFIX = `${RNX_SHELL_UPDATE_PREFIX}set:`;
|
|
21517
|
+
RNX_SHELL_UPDATE_UNSET = `${RNX_SHELL_UPDATE_PREFIX}unset`;
|
|
21518
|
+
}
|
|
21519
|
+
});
|
|
21520
|
+
|
|
21521
|
+
// cli/cloud-client.ts
|
|
21522
|
+
function isRecord4(value) {
|
|
21523
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
21524
|
+
}
|
|
21525
|
+
function responseError(status, text) {
|
|
21526
|
+
if (text) {
|
|
21527
|
+
try {
|
|
21528
|
+
const parsed = JSON.parse(text);
|
|
21529
|
+
const error = isRecord4(parsed) ? parsed.error : null;
|
|
21530
|
+
if (isRecord4(error) && typeof error.message === "string") {
|
|
21531
|
+
return new Error(`RNX Cloud request failed (${status}): ${error.message}`);
|
|
21532
|
+
}
|
|
21533
|
+
} catch {
|
|
21534
|
+
}
|
|
21535
|
+
}
|
|
21536
|
+
return new Error(
|
|
21537
|
+
`RNX Cloud request failed (${status})${text.trim() ? `: ${text.trim()}` : ""}`
|
|
21538
|
+
);
|
|
21539
|
+
}
|
|
21540
|
+
function resolveCloudSessionForParsed(parsed) {
|
|
21541
|
+
const session = readCloudSession();
|
|
21542
|
+
if (!session) return null;
|
|
21543
|
+
if (parsed.simIdSource === "flag" && parsed.simId !== session.simId) {
|
|
21544
|
+
throw new Error(
|
|
21545
|
+
`this shell is connected to RNX Cloud simulator ${session.simId}; ${parsed.simId ? `--sim ${parsed.simId}` : "the requested simulator"} is not available in this shell`
|
|
21546
|
+
);
|
|
21547
|
+
}
|
|
21548
|
+
return session;
|
|
21549
|
+
}
|
|
21550
|
+
function cloudCommand(command) {
|
|
21551
|
+
const clean = {};
|
|
21552
|
+
for (const [key, value] of Object.entries(command)) {
|
|
21553
|
+
if (key !== "id" && key !== "simId") clean[key] = value;
|
|
21554
|
+
}
|
|
21555
|
+
if (command.type === "query") {
|
|
21556
|
+
const query = command.query;
|
|
21557
|
+
if (!isRecord4(query) || query.kind !== "tree" && query.kind !== "find" && query.kind !== "count") {
|
|
21558
|
+
throw new Error("RNX Cloud supports only structured tree, node, and count queries");
|
|
21559
|
+
}
|
|
21560
|
+
return clean;
|
|
21561
|
+
}
|
|
21562
|
+
if (command.type === "waitFor") {
|
|
21563
|
+
const options = command.waitForOptions;
|
|
21564
|
+
const condition = isRecord4(options) ? options.condition : null;
|
|
21565
|
+
if (!isRecord4(condition) || condition.type !== "ready" && condition.type !== "present" && condition.type !== "absent") {
|
|
21566
|
+
throw new Error("RNX Cloud supports only ready and selector waits");
|
|
21567
|
+
}
|
|
21568
|
+
return clean;
|
|
21569
|
+
}
|
|
21570
|
+
if (command.type === "state") return clean;
|
|
21571
|
+
if (command.type === "capture" || command.type === "captureRegions") return clean;
|
|
21572
|
+
if (command.type === "setAppearance" || command.type === "openUrl") return clean;
|
|
21573
|
+
if (command.type === "screenshot" && command.crop === void 0 && command.captureFilter === void 0 && (command.layers === void 0 || command.layers === "tenant")) {
|
|
21574
|
+
return clean;
|
|
21575
|
+
}
|
|
21576
|
+
throw new Error(`RNX Cloud does not support bridge command type ${command.type}`);
|
|
21577
|
+
}
|
|
21578
|
+
function createCloudBridgeForParsed(parsed) {
|
|
21579
|
+
const session = resolveCloudSessionForParsed(parsed);
|
|
21580
|
+
return session ? new CloudBridge(session) : null;
|
|
21581
|
+
}
|
|
21582
|
+
var import_node_crypto5, DEFAULT_RNX_CLOUD_ORIGIN, CloudBridge;
|
|
21583
|
+
var init_cloud_client = __esm({
|
|
21584
|
+
"cli/cloud-client.ts"() {
|
|
21585
|
+
"use strict";
|
|
21586
|
+
import_node_crypto5 = require("node:crypto");
|
|
21587
|
+
init_cloud_contract();
|
|
21588
|
+
init_public_brand();
|
|
21589
|
+
init_cloud_session();
|
|
21590
|
+
DEFAULT_RNX_CLOUD_ORIGIN = rnxPublicBrand.origin;
|
|
21591
|
+
CloudBridge = class {
|
|
21592
|
+
constructor(session) {
|
|
21593
|
+
this.session = session;
|
|
21594
|
+
}
|
|
21595
|
+
plane = "cloud";
|
|
21596
|
+
async send(command, options) {
|
|
21597
|
+
const body = {
|
|
21598
|
+
id: (0, import_node_crypto5.randomUUID)(),
|
|
21599
|
+
claimId: this.session.claimId,
|
|
21600
|
+
command: cloudCommand(command)
|
|
21601
|
+
};
|
|
21602
|
+
let response;
|
|
21603
|
+
try {
|
|
21604
|
+
response = await fetch(
|
|
21605
|
+
`${this.session.apiOrigin}/v1/sims/${encodeURIComponent(this.session.simId)}/commands`,
|
|
21606
|
+
{
|
|
21607
|
+
method: "POST",
|
|
21608
|
+
headers: {
|
|
21609
|
+
authorization: `Bearer ${this.session.token}`,
|
|
21610
|
+
"content-type": "application/json"
|
|
21611
|
+
},
|
|
21612
|
+
body: JSON.stringify(body),
|
|
21613
|
+
...options?.timeoutMs ? { signal: AbortSignal.timeout(options.timeoutMs) } : {}
|
|
21614
|
+
}
|
|
21615
|
+
);
|
|
21616
|
+
} catch (error) {
|
|
21617
|
+
throw new Error(
|
|
21618
|
+
`could not reach RNX Cloud at ${this.session.apiOrigin}: ${error instanceof Error ? error.message : String(error)}`
|
|
21619
|
+
);
|
|
21620
|
+
}
|
|
21621
|
+
const text = await response.text();
|
|
21622
|
+
if (!response.ok) throw responseError(response.status, text);
|
|
21623
|
+
let parsed;
|
|
21624
|
+
try {
|
|
21625
|
+
parsed = JSON.parse(text);
|
|
21626
|
+
} catch {
|
|
21627
|
+
throw new Error("RNX Cloud command returned unreadable JSON");
|
|
21628
|
+
}
|
|
21629
|
+
if (!isRecord4(parsed) || parsed.id !== body.id) {
|
|
21630
|
+
throw new Error("RNX Cloud command returned an invalid command receipt");
|
|
21631
|
+
}
|
|
21632
|
+
if (typeof parsed.error === "string" && parsed.error) throw new Error(parsed.error);
|
|
21633
|
+
if (!Object.hasOwn(parsed, "result")) {
|
|
21634
|
+
throw new Error("RNX Cloud command receipt has no result");
|
|
21635
|
+
}
|
|
21636
|
+
return parsed.result;
|
|
21637
|
+
}
|
|
21638
|
+
listSims() {
|
|
21639
|
+
return Promise.reject(new Error("RNX Cloud does not expose a local simulator list"));
|
|
21640
|
+
}
|
|
21641
|
+
focusSim() {
|
|
21642
|
+
return Promise.reject(
|
|
21643
|
+
new Error("RNX Cloud simulators have no browser window to focus")
|
|
21644
|
+
);
|
|
21645
|
+
}
|
|
21646
|
+
closeSim() {
|
|
21647
|
+
return Promise.reject(new Error("RNX Cloud close uses the simulator DELETE route"));
|
|
21648
|
+
}
|
|
21649
|
+
claim() {
|
|
21650
|
+
return Promise.reject(new Error("RNX Cloud claim uses the simulator claim route"));
|
|
21651
|
+
}
|
|
21652
|
+
close() {
|
|
21653
|
+
}
|
|
21654
|
+
};
|
|
21655
|
+
}
|
|
21656
|
+
});
|
|
21657
|
+
|
|
21419
21658
|
// cli/parent-pid.ts
|
|
21420
21659
|
function getParentPid(pid) {
|
|
21421
21660
|
if (!cached3) cached3 = build2();
|
|
@@ -21575,6 +21814,36 @@ var init_parent_pid = __esm({
|
|
|
21575
21814
|
}
|
|
21576
21815
|
});
|
|
21577
21816
|
|
|
21817
|
+
// cli/secure-file.ts
|
|
21818
|
+
function writeSecureJsonAtomic(filepath, value) {
|
|
21819
|
+
(0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(filepath), { recursive: true });
|
|
21820
|
+
const temporary = `${filepath}.tmp-${process.pid}-${(0, import_node_crypto6.randomUUID)()}`;
|
|
21821
|
+
let descriptor = null;
|
|
21822
|
+
try {
|
|
21823
|
+
descriptor = (0, import_node_fs12.openSync)(temporary, "wx", 384);
|
|
21824
|
+
(0, import_node_fs12.fchmodSync)(descriptor, 384);
|
|
21825
|
+
(0, import_node_fs12.writeFileSync)(descriptor, `${JSON.stringify(value, null, 2)}
|
|
21826
|
+
`);
|
|
21827
|
+
(0, import_node_fs12.fsyncSync)(descriptor);
|
|
21828
|
+
(0, import_node_fs12.closeSync)(descriptor);
|
|
21829
|
+
descriptor = null;
|
|
21830
|
+
(0, import_node_fs12.renameSync)(temporary, filepath);
|
|
21831
|
+
} catch (error) {
|
|
21832
|
+
if (descriptor !== null) (0, import_node_fs12.closeSync)(descriptor);
|
|
21833
|
+
(0, import_node_fs12.rmSync)(temporary, { force: true });
|
|
21834
|
+
throw error;
|
|
21835
|
+
}
|
|
21836
|
+
}
|
|
21837
|
+
var import_node_crypto6, import_node_fs12, import_node_path13;
|
|
21838
|
+
var init_secure_file = __esm({
|
|
21839
|
+
"cli/secure-file.ts"() {
|
|
21840
|
+
"use strict";
|
|
21841
|
+
import_node_crypto6 = require("node:crypto");
|
|
21842
|
+
import_node_fs12 = require("node:fs");
|
|
21843
|
+
import_node_path13 = require("node:path");
|
|
21844
|
+
}
|
|
21845
|
+
});
|
|
21846
|
+
|
|
21578
21847
|
// cli/current-sim.ts
|
|
21579
21848
|
function findTopAncestor(start, maxDepth = 20) {
|
|
21580
21849
|
let prev = start;
|
|
@@ -21621,50 +21890,57 @@ function getCurrentSimPath() {
|
|
|
21621
21890
|
const key = getCliIdentityKey();
|
|
21622
21891
|
return (0, import_path3.join)((0, import_os.tmpdir)(), `rnx-current-sim-${key}.json`);
|
|
21623
21892
|
}
|
|
21624
|
-
function
|
|
21893
|
+
function legacyCloudCredentialDirectory(filepath) {
|
|
21894
|
+
return (0, import_path3.join)((0, import_path3.dirname)(filepath), `${(0, import_path3.basename)(filepath)}.credentials`);
|
|
21895
|
+
}
|
|
21896
|
+
function readCurrentTarget() {
|
|
21625
21897
|
const filepath = getCurrentSimPath();
|
|
21898
|
+
(0, import_fs4.rmSync)(legacyCloudCredentialDirectory(filepath), { recursive: true, force: true });
|
|
21626
21899
|
if (!(0, import_fs4.existsSync)(filepath)) return null;
|
|
21627
21900
|
try {
|
|
21628
21901
|
const parsed = JSON.parse((0, import_fs4.readFileSync)(filepath, "utf8"));
|
|
21629
|
-
if (parsed
|
|
21902
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
21630
21903
|
(0, import_fs4.rmSync)(filepath, { force: true });
|
|
21631
21904
|
return null;
|
|
21632
21905
|
}
|
|
21633
|
-
|
|
21906
|
+
const version = Reflect.get(parsed, "version");
|
|
21907
|
+
const plane = Reflect.get(parsed, "plane");
|
|
21908
|
+
const simId = Reflect.get(parsed, "simId");
|
|
21909
|
+
const updatedAt = Reflect.get(parsed, "updatedAt");
|
|
21910
|
+
if (version !== 1 && version !== CURRENT_SIM_VERSION || version === CURRENT_SIM_VERSION && plane !== "local" || typeof simId !== "string" || !simId.trim() || typeof updatedAt !== "string") {
|
|
21911
|
+
(0, import_fs4.rmSync)(filepath, { force: true });
|
|
21912
|
+
return null;
|
|
21913
|
+
}
|
|
21914
|
+
const target = {
|
|
21634
21915
|
version: CURRENT_SIM_VERSION,
|
|
21635
|
-
|
|
21636
|
-
|
|
21916
|
+
plane: "local",
|
|
21917
|
+
simId: simId.trim(),
|
|
21918
|
+
updatedAt
|
|
21637
21919
|
};
|
|
21920
|
+
if (version === 1) writeSecureJsonAtomic(filepath, target);
|
|
21921
|
+
return target;
|
|
21638
21922
|
} catch {
|
|
21639
21923
|
(0, import_fs4.rmSync)(filepath, { force: true });
|
|
21640
21924
|
return null;
|
|
21641
21925
|
}
|
|
21642
21926
|
}
|
|
21643
21927
|
function readCurrentSimId() {
|
|
21644
|
-
return
|
|
21928
|
+
return readCurrentTarget()?.simId ?? null;
|
|
21645
21929
|
}
|
|
21646
21930
|
function saveCurrentSimId(simId) {
|
|
21647
21931
|
const normalized = simId.trim();
|
|
21648
21932
|
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
|
-
);
|
|
21933
|
+
writeSecureJsonAtomic(getCurrentSimPath(), {
|
|
21934
|
+
version: CURRENT_SIM_VERSION,
|
|
21935
|
+
plane: "local",
|
|
21936
|
+
simId: normalized,
|
|
21937
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
21938
|
+
});
|
|
21663
21939
|
}
|
|
21664
21940
|
function clearCurrentSimId() {
|
|
21665
21941
|
(0, import_fs4.rmSync)(getCurrentSimPath(), { force: true });
|
|
21666
21942
|
}
|
|
21667
|
-
var import_fs4, import_os, import_path3, CURRENT_SIM_VERSION, CURRENT_SIM_PATH_ENV, IDENTITY_ENV_VARS, IMMORTAL_HOST_COMM_RE;
|
|
21943
|
+
var import_fs4, import_os, import_path3, CURRENT_SIM_VERSION, CURRENT_SIM_PATH_ENV, IDENTITY_ENV_VARS, IMMORTAL_HOST_COMM_RE, readCurrentSim;
|
|
21668
21944
|
var init_current_sim = __esm({
|
|
21669
21945
|
"cli/current-sim.ts"() {
|
|
21670
21946
|
"use strict";
|
|
@@ -21672,7 +21948,8 @@ var init_current_sim = __esm({
|
|
|
21672
21948
|
import_os = require("os");
|
|
21673
21949
|
import_path3 = require("path");
|
|
21674
21950
|
init_parent_pid();
|
|
21675
|
-
|
|
21951
|
+
init_secure_file();
|
|
21952
|
+
CURRENT_SIM_VERSION = 2;
|
|
21676
21953
|
CURRENT_SIM_PATH_ENV = "SOOTSIM_CLI_CURRENT_SIM_PATH";
|
|
21677
21954
|
IDENTITY_ENV_VARS = [
|
|
21678
21955
|
"RNX_CLI_IDENTITY",
|
|
@@ -21703,6 +21980,7 @@ var init_current_sim = __esm({
|
|
|
21703
21980
|
// vscode integrated terminal
|
|
21704
21981
|
];
|
|
21705
21982
|
IMMORTAL_HOST_COMM_RE = /^(?:tmux|screen)|^tm$/i;
|
|
21983
|
+
readCurrentSim = readCurrentTarget;
|
|
21706
21984
|
}
|
|
21707
21985
|
});
|
|
21708
21986
|
|
|
@@ -21736,17 +22014,17 @@ function liveDevBridgeLockfiles() {
|
|
|
21736
22014
|
return readDevBridgeLockfiles().filter((lockfile) => isDevBridgeLockfileFresh(lockfile));
|
|
21737
22015
|
}
|
|
21738
22016
|
function checkoutRoot(cwd) {
|
|
21739
|
-
let current =
|
|
22017
|
+
let current = import_node_path14.default.resolve(cwd);
|
|
21740
22018
|
while (true) {
|
|
21741
|
-
if (
|
|
21742
|
-
const parent =
|
|
22019
|
+
if (import_node_fs13.default.existsSync(import_node_path14.default.join(current, ".git"))) return current;
|
|
22020
|
+
const parent = import_node_path14.default.dirname(current);
|
|
21743
22021
|
if (parent === current) return null;
|
|
21744
22022
|
current = parent;
|
|
21745
22023
|
}
|
|
21746
22024
|
}
|
|
21747
22025
|
function pathContains(parent, child) {
|
|
21748
|
-
const relative =
|
|
21749
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
22026
|
+
const relative = import_node_path14.default.relative(parent, child);
|
|
22027
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${import_node_path14.default.sep}`) && !import_node_path14.default.isAbsolute(relative);
|
|
21750
22028
|
}
|
|
21751
22029
|
function resolveDefaultDevBridgeLockfile() {
|
|
21752
22030
|
const lockfiles = liveDevBridgeLockfiles();
|
|
@@ -21933,9 +22211,9 @@ function parseBridgeCliArgs(args, opts = {}) {
|
|
|
21933
22211
|
}
|
|
21934
22212
|
}
|
|
21935
22213
|
if (!simId) {
|
|
21936
|
-
const
|
|
21937
|
-
if (
|
|
21938
|
-
simId =
|
|
22214
|
+
const savedSim = readCurrentSim();
|
|
22215
|
+
if (savedSim) {
|
|
22216
|
+
simId = savedSim.simId.trim() || void 0;
|
|
21939
22217
|
simIdSource = "saved";
|
|
21940
22218
|
}
|
|
21941
22219
|
}
|
|
@@ -22031,6 +22309,7 @@ function createBridge(wsPort, opts = {}) {
|
|
|
22031
22309
|
}
|
|
22032
22310
|
});
|
|
22033
22311
|
return {
|
|
22312
|
+
plane: "local",
|
|
22034
22313
|
async send(cmd, callOpts) {
|
|
22035
22314
|
const effectiveTimeoutMs = callOpts?.timeoutMs ?? commandTimeoutMs;
|
|
22036
22315
|
const sendOnce = async (defaultSimId) => {
|
|
@@ -22113,6 +22392,8 @@ function createBridge(wsPort, opts = {}) {
|
|
|
22113
22392
|
};
|
|
22114
22393
|
}
|
|
22115
22394
|
function createBridgeFromParsed(parsed) {
|
|
22395
|
+
const cloudBridge = createCloudBridgeForParsed(parsed);
|
|
22396
|
+
if (cloudBridge) return cloudBridge;
|
|
22116
22397
|
return createBridge(parsed.wsPort, {
|
|
22117
22398
|
commandTimeoutMs: parsed.commandTimeoutMs,
|
|
22118
22399
|
simId: parsed.simId,
|
|
@@ -22175,16 +22456,17 @@ async function callInBridge(bridge, path20, ...args) {
|
|
|
22175
22456
|
async function callInBridgeWrite(bridge, path20, ...args) {
|
|
22176
22457
|
return bridge.send({ type: "call", path: path20, args, acquireLock: true });
|
|
22177
22458
|
}
|
|
22178
|
-
var
|
|
22459
|
+
var import_node_fs13, import_node_path14, import_ws3, RNX_PLACEMENT_ENV, resolvedWorld, BridgeSimLockedError;
|
|
22179
22460
|
var init_ws_bridge = __esm({
|
|
22180
22461
|
"cli/ws-bridge.ts"() {
|
|
22181
22462
|
"use strict";
|
|
22182
|
-
|
|
22183
|
-
|
|
22463
|
+
import_node_fs13 = __toESM(require("node:fs"), 1);
|
|
22464
|
+
import_node_path14 = __toESM(require("node:path"), 1);
|
|
22184
22465
|
import_ws3 = require("ws");
|
|
22185
22466
|
init_bridge_constants();
|
|
22186
22467
|
init_cli_constants();
|
|
22187
22468
|
init_home_paths();
|
|
22469
|
+
init_cloud_client();
|
|
22188
22470
|
init_current_sim();
|
|
22189
22471
|
RNX_PLACEMENT_ENV = "RNX_PLACEMENT";
|
|
22190
22472
|
resolvedWorld = null;
|
|
@@ -22220,9 +22502,8 @@ function isAppDeepLinkTarget(target) {
|
|
|
22220
22502
|
async function openAppUrl(bridge, target) {
|
|
22221
22503
|
const normalized = normalizeAppUrlTarget(target);
|
|
22222
22504
|
const result = await bridge.send({
|
|
22223
|
-
type: "
|
|
22224
|
-
|
|
22225
|
-
args: [normalized]
|
|
22505
|
+
type: "openUrl",
|
|
22506
|
+
url: normalized
|
|
22226
22507
|
});
|
|
22227
22508
|
if (result !== null && typeof result === "object" && Reflect.get(result, "ok") === false) {
|
|
22228
22509
|
const error = Reflect.get(result, "error");
|
|
@@ -22543,9 +22824,9 @@ var init_profiles = __esm({
|
|
|
22543
22824
|
// cli/app-project.ts
|
|
22544
22825
|
function firstNamedFile(dir, names) {
|
|
22545
22826
|
for (const name2 of names) {
|
|
22546
|
-
const candidate =
|
|
22827
|
+
const candidate = import_node_path15.default.join(dir, name2);
|
|
22547
22828
|
try {
|
|
22548
|
-
if (
|
|
22829
|
+
if (import_node_fs14.default.statSync(candidate).isFile()) return candidate;
|
|
22549
22830
|
} catch {
|
|
22550
22831
|
}
|
|
22551
22832
|
}
|
|
@@ -22558,24 +22839,24 @@ function findRNXAppConfig(dir) {
|
|
|
22558
22839
|
return firstNamedFile(dir, RNX_APP_CONFIG_NAMES);
|
|
22559
22840
|
}
|
|
22560
22841
|
function resolveAppProject(projectRoot) {
|
|
22561
|
-
const appDir =
|
|
22842
|
+
const appDir = import_node_path15.default.resolve(projectRoot);
|
|
22562
22843
|
try {
|
|
22563
|
-
if (!
|
|
22844
|
+
if (!import_node_fs14.default.statSync(appDir).isDirectory()) return null;
|
|
22564
22845
|
} catch {
|
|
22565
22846
|
return null;
|
|
22566
22847
|
}
|
|
22567
22848
|
const configPath = findRNXAppConfig(appDir);
|
|
22568
|
-
if (!configPath && !findExpoAppConfig(appDir) && !
|
|
22849
|
+
if (!configPath && !findExpoAppConfig(appDir) && !import_node_fs14.default.existsSync(import_node_path15.default.join(appDir, "package.json"))) {
|
|
22569
22850
|
return null;
|
|
22570
22851
|
}
|
|
22571
22852
|
return { appDir, configPath };
|
|
22572
22853
|
}
|
|
22573
|
-
var
|
|
22854
|
+
var import_node_fs14, import_node_path15, EXPO_APP_CONFIG_NAMES, RNX_APP_CONFIG_NAMES;
|
|
22574
22855
|
var init_app_project = __esm({
|
|
22575
22856
|
"cli/app-project.ts"() {
|
|
22576
22857
|
"use strict";
|
|
22577
|
-
|
|
22578
|
-
|
|
22858
|
+
import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
22859
|
+
import_node_path15 = __toESM(require("node:path"), 1);
|
|
22579
22860
|
EXPO_APP_CONFIG_NAMES = [
|
|
22580
22861
|
"app.config.js",
|
|
22581
22862
|
"app.config.ts",
|
|
@@ -22604,13 +22885,13 @@ function isRNXConfig(value) {
|
|
|
22604
22885
|
}
|
|
22605
22886
|
function resolveConfigReplacementFiles(config, configPath) {
|
|
22606
22887
|
if (!config.modules) return config;
|
|
22607
|
-
const configDir =
|
|
22888
|
+
const configDir = import_node_path16.default.dirname(configPath);
|
|
22608
22889
|
return {
|
|
22609
22890
|
...config,
|
|
22610
22891
|
modules: Object.fromEntries(
|
|
22611
22892
|
Object.entries(config.modules).map(([name2, resolution]) => [
|
|
22612
22893
|
name2,
|
|
22613
|
-
resolution && typeof resolution === "object" && "file" in resolution ? { ...resolution, file:
|
|
22894
|
+
resolution && typeof resolution === "object" && "file" in resolution ? { ...resolution, file: import_node_path16.default.resolve(configDir, resolution.file) } : resolution
|
|
22614
22895
|
])
|
|
22615
22896
|
)
|
|
22616
22897
|
};
|
|
@@ -22640,12 +22921,12 @@ async function resolveRNXAppConfig(startDir = process.cwd()) {
|
|
|
22640
22921
|
const project = resolveAppProject(startDir);
|
|
22641
22922
|
return { project, config: await loadRNXAppConfig(project) };
|
|
22642
22923
|
}
|
|
22643
|
-
var import_node_module,
|
|
22924
|
+
var import_node_module, import_node_path16, import_jiti, require2;
|
|
22644
22925
|
var init_app_config = __esm({
|
|
22645
22926
|
"cli/app-config.ts"() {
|
|
22646
22927
|
"use strict";
|
|
22647
22928
|
import_node_module = require("node:module");
|
|
22648
|
-
|
|
22929
|
+
import_node_path16 = __toESM(require("node:path"), 1);
|
|
22649
22930
|
init_src();
|
|
22650
22931
|
import_jiti = require("jiti");
|
|
22651
22932
|
init_public_brand();
|
|
@@ -22713,13 +22994,13 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
22713
22994
|
scannedFontDirectories++;
|
|
22714
22995
|
let entries;
|
|
22715
22996
|
try {
|
|
22716
|
-
entries =
|
|
22997
|
+
entries = import_node_fs15.default.readdirSync(current.dir, { withFileTypes: true });
|
|
22717
22998
|
} catch {
|
|
22718
22999
|
continue;
|
|
22719
23000
|
}
|
|
22720
23001
|
for (const entry of entries) {
|
|
22721
23002
|
if (entry.isSymbolicLink()) continue;
|
|
22722
|
-
const fullPath =
|
|
23003
|
+
const fullPath = import_node_path17.default.join(current.dir, entry.name);
|
|
22723
23004
|
if (entry.isDirectory()) {
|
|
22724
23005
|
if (current.depth < 4 && pending.length < 64 && !entry.name.startsWith(".")) {
|
|
22725
23006
|
pending.push({ dir: fullPath, depth: current.depth + 1 });
|
|
@@ -22727,15 +23008,15 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
22727
23008
|
continue;
|
|
22728
23009
|
}
|
|
22729
23010
|
if (!entry.isFile() || !/\.(ttf|otf|woff|woff2)$/i.test(entry.name)) continue;
|
|
22730
|
-
const relative =
|
|
22731
|
-
fontPaths.push(
|
|
23011
|
+
const relative = import_node_path17.default.relative(root, fullPath).split(import_node_path17.default.sep).join("/");
|
|
23012
|
+
fontPaths.push(import_node_path17.default.posix.join(metroPathPrefix, relative));
|
|
22732
23013
|
if (fontPaths.length >= 256) break;
|
|
22733
23014
|
}
|
|
22734
23015
|
}
|
|
22735
23016
|
};
|
|
22736
23017
|
try {
|
|
22737
23018
|
const packageJson = JSON.parse(
|
|
22738
|
-
|
|
23019
|
+
import_node_fs15.default.readFileSync(import_node_path17.default.join(selectedAppDir, "package.json"), "utf8")
|
|
22739
23020
|
);
|
|
22740
23021
|
const dependencyNames = /* @__PURE__ */ new Set();
|
|
22741
23022
|
for (const field of ["dependencies", "devDependencies", "optionalDependencies"]) {
|
|
@@ -22750,24 +23031,24 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
22750
23031
|
const config = Reflect.get(packageJson, "reactNativeVectorIcons");
|
|
22751
23032
|
const configuredFontDir = config && typeof config === "object" ? Reflect.get(config, "fontDir") : null;
|
|
22752
23033
|
const configuredDir = typeof configuredFontDir === "string" ? configuredFontDir : "rnvi-fonts";
|
|
22753
|
-
const root =
|
|
22754
|
-
const relativeRoot =
|
|
22755
|
-
if (!relativeRoot.startsWith("..") && !
|
|
22756
|
-
collectFontFiles(root, relativeRoot.split(
|
|
23034
|
+
const root = import_node_path17.default.resolve(selectedAppDir, configuredDir);
|
|
23035
|
+
const relativeRoot = import_node_path17.default.relative(selectedAppDir, root);
|
|
23036
|
+
if (!relativeRoot.startsWith("..") && !import_node_path17.default.isAbsolute(relativeRoot)) {
|
|
23037
|
+
collectFontFiles(root, relativeRoot.split(import_node_path17.default.sep).join("/"));
|
|
22757
23038
|
}
|
|
22758
|
-
const vectorIconRequire = (0, import_node_module2.createRequire)(
|
|
23039
|
+
const vectorIconRequire = (0, import_node_module2.createRequire)(import_node_path17.default.join(selectedAppDir, "package.json"));
|
|
22759
23040
|
for (const dependencyName of vectorIconDependencies) {
|
|
22760
23041
|
try {
|
|
22761
23042
|
const entryPath = vectorIconRequire.resolve(dependencyName);
|
|
22762
|
-
const dependencyPath = dependencyName.split("/").join(
|
|
22763
|
-
const marker = `${
|
|
23043
|
+
const dependencyPath = dependencyName.split("/").join(import_node_path17.default.sep);
|
|
23044
|
+
const marker = `${import_node_path17.default.sep}node_modules${import_node_path17.default.sep}${dependencyPath}${import_node_path17.default.sep}`;
|
|
22764
23045
|
const markerIndex = entryPath.lastIndexOf(marker);
|
|
22765
23046
|
if (markerIndex === -1) continue;
|
|
22766
23047
|
const packageRoot = entryPath.slice(0, markerIndex + marker.length - 1);
|
|
22767
23048
|
const fontsDir = dependencyName === "react-native-vector-icons" ? "Fonts" : "fonts";
|
|
22768
23049
|
collectFontFiles(
|
|
22769
|
-
|
|
22770
|
-
|
|
23050
|
+
import_node_path17.default.join(packageRoot, fontsDir),
|
|
23051
|
+
import_node_path17.default.posix.join("node_modules", dependencyName, fontsDir)
|
|
22771
23052
|
);
|
|
22772
23053
|
} catch {
|
|
22773
23054
|
}
|
|
@@ -22776,37 +23057,37 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
22776
23057
|
} catch {
|
|
22777
23058
|
}
|
|
22778
23059
|
try {
|
|
22779
|
-
const configPath =
|
|
22780
|
-
if (
|
|
22781
|
-
const appConfigRequire = (0, import_node_module2.createRequire)(
|
|
23060
|
+
const configPath = import_node_path17.default.join(selectedAppDir, "react-native.config.js");
|
|
23061
|
+
if (import_node_fs15.default.statSync(configPath).isFile()) {
|
|
23062
|
+
const appConfigRequire = (0, import_node_module2.createRequire)(import_node_path17.default.join(selectedAppDir, "package.json"));
|
|
22782
23063
|
const rnConfig = appConfigRequire(configPath);
|
|
22783
23064
|
const assets = rnConfig && typeof rnConfig === "object" ? Reflect.get(rnConfig, "assets") : null;
|
|
22784
23065
|
if (Array.isArray(assets)) {
|
|
22785
23066
|
for (const assetDir of assets) {
|
|
22786
23067
|
if (typeof assetDir !== "string") continue;
|
|
22787
|
-
const root =
|
|
22788
|
-
const relativeRoot =
|
|
22789
|
-
if (relativeRoot.startsWith("..") ||
|
|
22790
|
-
collectFontFiles(root, relativeRoot.split(
|
|
23068
|
+
const root = import_node_path17.default.resolve(selectedAppDir, assetDir);
|
|
23069
|
+
const relativeRoot = import_node_path17.default.relative(selectedAppDir, root);
|
|
23070
|
+
if (relativeRoot.startsWith("..") || import_node_path17.default.isAbsolute(relativeRoot)) continue;
|
|
23071
|
+
collectFontFiles(root, relativeRoot.split(import_node_path17.default.sep).join("/"));
|
|
22791
23072
|
}
|
|
22792
23073
|
}
|
|
22793
23074
|
}
|
|
22794
23075
|
} catch {
|
|
22795
23076
|
}
|
|
22796
23077
|
if (platform === "ios") {
|
|
22797
|
-
const iosDir =
|
|
23078
|
+
const iosDir = import_node_path17.default.join(selectedAppDir, "ios");
|
|
22798
23079
|
try {
|
|
22799
|
-
const targetDirs =
|
|
23080
|
+
const targetDirs = import_node_fs15.default.readdirSync(iosDir, { withFileTypes: true }).filter(
|
|
22800
23081
|
(entry) => entry.isDirectory() && !entry.isSymbolicLink() && entry.name !== "Pods" && entry.name !== "build" && !entry.name.startsWith(".")
|
|
22801
23082
|
).slice(0, 64);
|
|
22802
|
-
const plistPaths = [
|
|
23083
|
+
const plistPaths = [import_node_path17.default.join(iosDir, "Info.plist")];
|
|
22803
23084
|
for (const entry of targetDirs) {
|
|
22804
|
-
plistPaths.push(
|
|
23085
|
+
plistPaths.push(import_node_path17.default.join(iosDir, entry.name, "Info.plist"));
|
|
22805
23086
|
}
|
|
22806
23087
|
for (const plistPath of plistPaths) {
|
|
22807
23088
|
let parsed;
|
|
22808
23089
|
try {
|
|
22809
|
-
parsed = parsePlistSource(
|
|
23090
|
+
parsed = parsePlistSource(import_node_fs15.default.readFileSync(plistPath, "utf8"));
|
|
22810
23091
|
} catch {
|
|
22811
23092
|
continue;
|
|
22812
23093
|
}
|
|
@@ -22816,21 +23097,21 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
22816
23097
|
for (const declaredFont of declaredFonts) {
|
|
22817
23098
|
if (typeof declaredFont !== "string") continue;
|
|
22818
23099
|
const candidates = [
|
|
22819
|
-
|
|
22820
|
-
|
|
23100
|
+
import_node_path17.default.resolve(import_node_path17.default.dirname(plistPath), declaredFont),
|
|
23101
|
+
import_node_path17.default.resolve(iosDir, declaredFont)
|
|
22821
23102
|
];
|
|
22822
23103
|
const fontPath = candidates.find((candidate) => {
|
|
22823
|
-
const relative =
|
|
22824
|
-
if (relative.startsWith("..") ||
|
|
23104
|
+
const relative = import_node_path17.default.relative(selectedAppDir, candidate);
|
|
23105
|
+
if (relative.startsWith("..") || import_node_path17.default.isAbsolute(relative)) return false;
|
|
22825
23106
|
try {
|
|
22826
|
-
return
|
|
23107
|
+
return import_node_fs15.default.statSync(candidate).isFile();
|
|
22827
23108
|
} catch {
|
|
22828
23109
|
return false;
|
|
22829
23110
|
}
|
|
22830
23111
|
});
|
|
22831
23112
|
if (!fontPath) continue;
|
|
22832
23113
|
fontPaths.push(
|
|
22833
|
-
|
|
23114
|
+
import_node_path17.default.relative(selectedAppDir, fontPath).split(import_node_path17.default.sep).join("/")
|
|
22834
23115
|
);
|
|
22835
23116
|
}
|
|
22836
23117
|
}
|
|
@@ -22869,13 +23150,13 @@ async function resolveMetroProjectRoot(bundleUrl, opts) {
|
|
|
22869
23150
|
function encodeAppFontsWire(specs) {
|
|
22870
23151
|
return specs.map((spec) => `${encodeURIComponent(spec.url)}::${encodeURIComponent(spec.family)}`).join(",");
|
|
22871
23152
|
}
|
|
22872
|
-
var
|
|
23153
|
+
var import_node_fs15, import_node_module2, import_node_path17, import_config_plugin_fonts, require3;
|
|
22873
23154
|
var init_app_fonts = __esm({
|
|
22874
23155
|
"cli/app-fonts.ts"() {
|
|
22875
23156
|
"use strict";
|
|
22876
|
-
|
|
23157
|
+
import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
22877
23158
|
import_node_module2 = require("node:module");
|
|
22878
|
-
|
|
23159
|
+
import_node_path17 = __toESM(require("node:path"), 1);
|
|
22879
23160
|
import_config_plugin_fonts = require("sootsim-engine/engine/config-plugin-fonts");
|
|
22880
23161
|
init_dev_server_scanner();
|
|
22881
23162
|
init_plist();
|
|
@@ -23953,7 +24234,7 @@ var init_browser_cache = __esm({
|
|
|
23953
24234
|
});
|
|
23954
24235
|
|
|
23955
24236
|
// cli/drivers/playwright-provisioning.ts
|
|
23956
|
-
function
|
|
24237
|
+
function isRecord5(value) {
|
|
23957
24238
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23958
24239
|
}
|
|
23959
24240
|
function resolvePlaywright() {
|
|
@@ -23966,20 +24247,20 @@ function resolvePlaywright() {
|
|
|
23966
24247
|
try {
|
|
23967
24248
|
const modulePath = requireFromRoot.resolve(spec);
|
|
23968
24249
|
const packageJsonPath = requireFromRoot.resolve(`${spec}/package.json`);
|
|
23969
|
-
const parsed = JSON.parse((0,
|
|
23970
|
-
if (!
|
|
24250
|
+
const parsed = JSON.parse((0, import_node_fs16.readFileSync)(packageJsonPath, "utf8"));
|
|
24251
|
+
if (!isRecord5(parsed) || typeof parsed.version !== "string") continue;
|
|
23971
24252
|
const bin = parsed.bin;
|
|
23972
24253
|
let binPath = null;
|
|
23973
24254
|
if (typeof bin === "string") {
|
|
23974
24255
|
binPath = bin;
|
|
23975
|
-
} else if (
|
|
24256
|
+
} else if (isRecord5(bin)) {
|
|
23976
24257
|
const named = bin.playwright ?? bin["playwright-core"];
|
|
23977
24258
|
const first = Object.values(bin).find((value) => typeof value === "string");
|
|
23978
24259
|
binPath = typeof named === "string" ? named : typeof first === "string" ? first : null;
|
|
23979
24260
|
}
|
|
23980
24261
|
if (!binPath) continue;
|
|
23981
|
-
const cliPath = (0,
|
|
23982
|
-
if (!(0,
|
|
24262
|
+
const cliPath = (0, import_node_path18.join)((0, import_node_path18.dirname)(packageJsonPath), binPath);
|
|
24263
|
+
if (!(0, import_node_fs16.existsSync)(cliPath)) continue;
|
|
23983
24264
|
return {
|
|
23984
24265
|
spec,
|
|
23985
24266
|
modulePath,
|
|
@@ -24012,13 +24293,13 @@ function probeBrowser(resolved, env) {
|
|
|
24012
24293
|
}
|
|
24013
24294
|
try {
|
|
24014
24295
|
const parsed = JSON.parse(probe3.stdout);
|
|
24015
|
-
if (!
|
|
24296
|
+
if (!isRecord5(parsed) || typeof parsed.executablePath !== "string" || typeof parsed.exists !== "boolean") {
|
|
24016
24297
|
throw new Error("probe returned an invalid result");
|
|
24017
24298
|
}
|
|
24018
24299
|
return {
|
|
24019
24300
|
ok: true,
|
|
24020
24301
|
executablePath: parsed.executablePath,
|
|
24021
|
-
exists: parsed.exists && (0,
|
|
24302
|
+
exists: parsed.exists && (0, import_node_fs16.existsSync)(parsed.executablePath)
|
|
24022
24303
|
};
|
|
24023
24304
|
} catch (error) {
|
|
24024
24305
|
return {
|
|
@@ -24057,14 +24338,14 @@ ${detail}` : ""}`
|
|
|
24057
24338
|
}
|
|
24058
24339
|
return { ok: true, executablePath: after.executablePath, installed: true };
|
|
24059
24340
|
}
|
|
24060
|
-
var import_node_child_process6,
|
|
24341
|
+
var import_node_child_process6, import_node_fs16, import_node_module4, import_node_path18, PLAYWRIGHT_BROWSER_PROBE;
|
|
24061
24342
|
var init_playwright_provisioning = __esm({
|
|
24062
24343
|
"cli/drivers/playwright-provisioning.ts"() {
|
|
24063
24344
|
"use strict";
|
|
24064
24345
|
import_node_child_process6 = require("node:child_process");
|
|
24065
|
-
|
|
24346
|
+
import_node_fs16 = require("node:fs");
|
|
24066
24347
|
import_node_module4 = require("node:module");
|
|
24067
|
-
|
|
24348
|
+
import_node_path18 = require("node:path");
|
|
24068
24349
|
PLAYWRIGHT_BROWSER_PROBE = `
|
|
24069
24350
|
const { existsSync } = require('node:fs');
|
|
24070
24351
|
const modulePath = process.env.SOOTSIM_PW_MODULE;
|
|
@@ -24474,7 +24755,7 @@ const cleanupProfile = () => {
|
|
|
24474
24755
|
// we are spawned detached + unref'd so \`rnx open\` returns immediately,
|
|
24475
24756
|
// which means nothing in the OS process tree ties Chrome's lifetime to the
|
|
24476
24757
|
// session that asked for it. once the sim connects, the connect-timeout
|
|
24477
|
-
// safety net is cleared, so absent an explicit \`
|
|
24758
|
+
// safety net is cleared, so absent an explicit \`rnx close\` (or the
|
|
24478
24759
|
// daemon's idle reaper closing the sim socket) the host would hold Chrome
|
|
24479
24760
|
// open forever after its owner exits. poll the owning session's pid and tear
|
|
24480
24761
|
// down when it's gone. ESRCH (kill throws) = owner exited; EPERM = alive but
|
|
@@ -24765,10 +25046,10 @@ var init_run_rnx = __esm({
|
|
|
24765
25046
|
});
|
|
24766
25047
|
|
|
24767
25048
|
// cli/commands/inspect/env.ts
|
|
24768
|
-
function isAgentEnv() {
|
|
24769
|
-
if (
|
|
25049
|
+
function isAgentEnv(env = process.env) {
|
|
25050
|
+
if (env.RNX_AGENT === "0") return false;
|
|
24770
25051
|
for (const name2 of AGENT_ENV_VARS) {
|
|
24771
|
-
const v =
|
|
25052
|
+
const v = env[name2];
|
|
24772
25053
|
if (v && v.trim() && v !== "0") return true;
|
|
24773
25054
|
}
|
|
24774
25055
|
return false;
|
|
@@ -24933,7 +25214,7 @@ async function activateVersion(version) {
|
|
|
24933
25214
|
const notified = await tellDaemonRuntimeChanged(version);
|
|
24934
25215
|
if (!notified) {
|
|
24935
25216
|
console.log(
|
|
24936
|
-
` (no daemon running \u2014 next
|
|
25217
|
+
` (no daemon running \u2014 next rnx/electron launch will pick up ${version})`
|
|
24937
25218
|
);
|
|
24938
25219
|
}
|
|
24939
25220
|
}
|
|
@@ -25240,14 +25521,14 @@ function assertExplicitBridgeLock(preferredPort, explicitPort, lock) {
|
|
|
25240
25521
|
}
|
|
25241
25522
|
async function ensureRuntimeForOpen() {
|
|
25242
25523
|
const active = readActiveRuntime();
|
|
25243
|
-
if (active &&
|
|
25524
|
+
if (active && import_node_fs17.default.existsSync(runtimeDir(active))) return;
|
|
25244
25525
|
console.error(" installing rnx engine runtime...");
|
|
25245
25526
|
const { runRuntime: runRuntime2 } = await Promise.resolve().then(() => (init_runtime(), runtime_exports));
|
|
25246
25527
|
await runRuntime2(["install"], {});
|
|
25247
25528
|
}
|
|
25248
25529
|
function spawnSootsim(args) {
|
|
25249
25530
|
const entry = process.argv[1];
|
|
25250
|
-
if (entry &&
|
|
25531
|
+
if (entry && import_node_fs17.default.existsSync(entry)) {
|
|
25251
25532
|
return (0, import_node_child_process7.spawn)(process.execPath, [entry, ...args], {
|
|
25252
25533
|
detached: true,
|
|
25253
25534
|
stdio: "ignore",
|
|
@@ -25394,10 +25675,10 @@ async function buildResolvedBundleOpenUrl(target, baseUrl, opts = {}) {
|
|
|
25394
25675
|
}
|
|
25395
25676
|
function normalizeReplacementPath(filePath) {
|
|
25396
25677
|
if (filePath.startsWith("~/")) {
|
|
25397
|
-
return
|
|
25678
|
+
return import_node_path19.default.join(import_node_os3.default.homedir(), filePath.slice(2));
|
|
25398
25679
|
}
|
|
25399
|
-
if (
|
|
25400
|
-
return
|
|
25680
|
+
if (import_node_path19.default.isAbsolute(filePath)) return filePath;
|
|
25681
|
+
return import_node_path19.default.resolve(process.cwd(), filePath);
|
|
25401
25682
|
}
|
|
25402
25683
|
function parseOpenRuntimeConfig(args) {
|
|
25403
25684
|
const modules = {};
|
|
@@ -25416,7 +25697,7 @@ function parseOpenRuntimeConfig(args) {
|
|
|
25416
25697
|
}
|
|
25417
25698
|
const moduleName = raw.slice(0, eqIndex).trim();
|
|
25418
25699
|
const filePath = normalizeReplacementPath(raw.slice(eqIndex + 1).trim());
|
|
25419
|
-
if (!
|
|
25700
|
+
if (!import_node_fs17.default.existsSync(filePath)) {
|
|
25420
25701
|
console.error(` rnx open: replacement file not found: ${filePath}`);
|
|
25421
25702
|
rnxExit(1);
|
|
25422
25703
|
}
|
|
@@ -25447,7 +25728,7 @@ async function resolveOpenAppProject(resolvedBundle) {
|
|
|
25447
25728
|
return advertisedRoot ? resolveAppProject(advertisedRoot) : null;
|
|
25448
25729
|
}
|
|
25449
25730
|
async function ensureConfiguredRuntime(version) {
|
|
25450
|
-
if (
|
|
25731
|
+
if (import_node_fs17.default.existsSync(import_node_path19.default.join(runtimeDir(version), "index.html"))) return;
|
|
25451
25732
|
console.error(` installing configured engine runtime ${version}...`);
|
|
25452
25733
|
const result = await rnxRuntime.install({
|
|
25453
25734
|
version,
|
|
@@ -25807,7 +26088,7 @@ function playwrightHostPidForSim(sim) {
|
|
|
25807
26088
|
function signalDriverLaunchConnected(result) {
|
|
25808
26089
|
if (!result.connectAckFile) return false;
|
|
25809
26090
|
try {
|
|
25810
|
-
|
|
26091
|
+
import_node_fs17.default.writeFileSync(
|
|
25811
26092
|
result.connectAckFile,
|
|
25812
26093
|
`${JSON.stringify({ connectedAt: Date.now(), pid: result.pid ?? null })}
|
|
25813
26094
|
`,
|
|
@@ -25821,19 +26102,19 @@ function signalDriverLaunchConnected(result) {
|
|
|
25821
26102
|
function printDriverDiagnosticLogTail(result) {
|
|
25822
26103
|
if (!result.diagnosticLogPath) return;
|
|
25823
26104
|
try {
|
|
25824
|
-
const detail =
|
|
26105
|
+
const detail = import_node_fs17.default.readFileSync(result.diagnosticLogPath, "utf8").trim();
|
|
25825
26106
|
if (!detail) {
|
|
25826
|
-
console.error(` ${
|
|
26107
|
+
console.error(` ${import_node_path19.default.basename(result.diagnosticLogPath)} was empty`);
|
|
25827
26108
|
return;
|
|
25828
26109
|
}
|
|
25829
26110
|
const shown = detail.length > 4e3 ? `\u2026
|
|
25830
26111
|
${detail.slice(-4e3)}` : detail;
|
|
25831
|
-
console.error(` ${
|
|
26112
|
+
console.error(` ${import_node_path19.default.basename(result.diagnosticLogPath)}:`);
|
|
25832
26113
|
console.error(shown);
|
|
25833
26114
|
} catch (err) {
|
|
25834
26115
|
const message = err instanceof Error ? err.message : String(err);
|
|
25835
26116
|
console.error(
|
|
25836
|
-
` failed to read ${
|
|
26117
|
+
` failed to read ${import_node_path19.default.basename(result.diagnosticLogPath)}: ${message}`
|
|
25837
26118
|
);
|
|
25838
26119
|
}
|
|
25839
26120
|
}
|
|
@@ -26644,14 +26925,14 @@ async function runCloseCommand(args, opts = {}) {
|
|
|
26644
26925
|
bridge.close();
|
|
26645
26926
|
}
|
|
26646
26927
|
}
|
|
26647
|
-
var import_node_child_process7,
|
|
26928
|
+
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
26929
|
var init_control = __esm({
|
|
26649
26930
|
"cli/commands/control.ts"() {
|
|
26650
26931
|
"use strict";
|
|
26651
26932
|
import_node_child_process7 = require("node:child_process");
|
|
26652
|
-
|
|
26933
|
+
import_node_fs17 = __toESM(require("node:fs"), 1);
|
|
26653
26934
|
import_node_os3 = __toESM(require("node:os"), 1);
|
|
26654
|
-
|
|
26935
|
+
import_node_path19 = __toESM(require("node:path"), 1);
|
|
26655
26936
|
import_settings = require("sootsim-engine/settings");
|
|
26656
26937
|
import_ws5 = require("ws");
|
|
26657
26938
|
init_dev_server_scanner();
|
|
@@ -27515,14 +27796,14 @@ process.stdin.on('end', async () => {
|
|
|
27515
27796
|
function getBaseDir() {
|
|
27516
27797
|
const explicit = process.env[SESSION_FILE_ENV];
|
|
27517
27798
|
if (explicit?.trim()) {
|
|
27518
|
-
return (0,
|
|
27799
|
+
return (0, import_node_path20.dirname)((0, import_node_path20.resolve)(explicit));
|
|
27519
27800
|
}
|
|
27520
27801
|
return electronUserDataDir();
|
|
27521
27802
|
}
|
|
27522
27803
|
function getSharedDesktopAuthFilePath() {
|
|
27523
27804
|
const explicit = process.env[SESSION_FILE_ENV];
|
|
27524
|
-
if (explicit?.trim()) return (0,
|
|
27525
|
-
return (0,
|
|
27805
|
+
if (explicit?.trim()) return (0, import_node_path20.resolve)(explicit);
|
|
27806
|
+
return (0, import_node_path20.join)(getBaseDir(), "desktop-auth.json");
|
|
27526
27807
|
}
|
|
27527
27808
|
function normalizeUser(input) {
|
|
27528
27809
|
if (!input || typeof input !== "object") return null;
|
|
@@ -27569,26 +27850,26 @@ function normalizeSession(input) {
|
|
|
27569
27850
|
}
|
|
27570
27851
|
function readSharedDesktopAuthSession() {
|
|
27571
27852
|
const filepath = getSharedDesktopAuthFilePath();
|
|
27572
|
-
if (!(0,
|
|
27853
|
+
if (!(0, import_node_fs18.existsSync)(filepath)) return null;
|
|
27573
27854
|
try {
|
|
27574
|
-
const parsed = JSON.parse((0,
|
|
27855
|
+
const parsed = JSON.parse((0, import_node_fs18.readFileSync)(filepath, "utf8"));
|
|
27575
27856
|
const normalized = normalizeSession(parsed);
|
|
27576
27857
|
if (!normalized) {
|
|
27577
|
-
(0,
|
|
27858
|
+
(0, import_node_fs18.rmSync)(filepath, { force: true });
|
|
27578
27859
|
return null;
|
|
27579
27860
|
}
|
|
27580
27861
|
return normalized;
|
|
27581
27862
|
} catch {
|
|
27582
|
-
(0,
|
|
27863
|
+
(0, import_node_fs18.rmSync)(filepath, { force: true });
|
|
27583
27864
|
return null;
|
|
27584
27865
|
}
|
|
27585
27866
|
}
|
|
27586
|
-
var
|
|
27867
|
+
var import_node_fs18, import_node_path20, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
|
|
27587
27868
|
var init_shared_session = __esm({
|
|
27588
27869
|
"src/auth/shared-session.ts"() {
|
|
27589
27870
|
"use strict";
|
|
27590
|
-
|
|
27591
|
-
|
|
27871
|
+
import_node_fs18 = require("node:fs");
|
|
27872
|
+
import_node_path20 = require("node:path");
|
|
27592
27873
|
init_home_paths();
|
|
27593
27874
|
SESSION_VERSION = 1;
|
|
27594
27875
|
SESSION_FILE_ENV = "SOOTSIM_SHARED_AUTH_FILE";
|
|
@@ -29176,7 +29457,7 @@ var init_bridge_flow_runner = __esm({
|
|
|
29176
29457
|
await this.resetGuestAppData();
|
|
29177
29458
|
await this.rearmCaptureAfterRuntimeReload();
|
|
29178
29459
|
}
|
|
29179
|
-
// maestro clearKeychain: there is no real keychain in
|
|
29460
|
+
// maestro clearKeychain: there is no real keychain in rnx's browser
|
|
29180
29461
|
// sandbox. log loudly so the author notices, then continue — matching the
|
|
29181
29462
|
// "loud warning, not silent skip" policy in the plan.
|
|
29182
29463
|
clearKeychain() {
|