rnxsim 0.1.431 → 0.1.433
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 +20 -50
- package/cli/auth.ts +33 -3
- package/cli/cloud-client.ts +524 -88
- package/cli/cloud-dispatch.ts +5 -10
- package/cli/cloud-session.ts +5 -5
- package/cli/commands/auth.ts +13 -2
- package/cli/commands/box.ts +189 -20
- package/cli/commands/control.ts +40 -13
- package/cli/commands/device.ts +1 -1
- package/cli/commands/flow.ts +189 -43
- package/cli/commands/inspect/get-layout.ts +1 -1
- package/cli/commands/inspect.ts +8 -1
- package/cli/commands/login.ts +79 -14
- package/cli/commands/maestro-generate.ts +70 -54
- package/cli/commands/maestro.ts +69 -20
- package/cli/commands/platform.ts +30 -32
- package/cli/commands/screenshot.ts +3 -2
- package/cli/commands/upload.ts +28 -10
- package/cli/help-core.ts +11 -1
- package/cli/outbound-endpoints.ts +27 -5
- package/cli/parse-args.ts +17 -0
- package/cli/shell-init.ts +4 -4
- package/cli/ws-bridge.ts +109 -62
- 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 +17 -4
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud.cjs +108 -93
- package/dist-lib/cloud.mjs +106 -91
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +1 -1
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +58 -139
- 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-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.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 +33 -212
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +436 -351
- package/dist-lib/vite.cjs +1 -1
- package/package.json +2 -1
- package/src/auth/shared-session.ts +31 -0
- package/src/cloud.ts +83 -113
- package/src/metro-plugin.ts +30 -113
- package/src/vite-plugin.ts +11 -2
package/dist-lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.433 | (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;
|
|
@@ -569,6 +569,10 @@ var rnxPublicBrand = Object.freeze({
|
|
|
569
569
|
origin: "https://rnxsim.com"
|
|
570
570
|
});
|
|
571
571
|
|
|
572
|
+
// cli/run-rnx.ts
|
|
573
|
+
var import_node_async_hooks = require("node:async_hooks");
|
|
574
|
+
var sinks = new import_node_async_hooks.AsyncLocalStorage();
|
|
575
|
+
|
|
572
576
|
// src/backend-origin.ts
|
|
573
577
|
function normalizeHostname(hostname) {
|
|
574
578
|
return hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
@@ -586,6 +590,8 @@ var RNX_SHELL_UPDATE_UNSET = `${RNX_SHELL_UPDATE_PREFIX}unset`;
|
|
|
586
590
|
|
|
587
591
|
// cli/cloud-client.ts
|
|
588
592
|
var DEFAULT_RNX_CLOUD_ORIGIN = rnxPublicBrand.origin;
|
|
593
|
+
var MAX_RNX_CLOUD_BUNDLE_BYTES = RNX_CLOUD_MAX_ARTIFACT_BYTES;
|
|
594
|
+
var WARN_ARTIFACT_BYTES = Math.floor(MAX_RNX_CLOUD_BUNDLE_BYTES * 0.8);
|
|
589
595
|
|
|
590
596
|
// cli/ws-bridge.ts
|
|
591
597
|
function bridgeWsUrl(wsPort) {
|
|
@@ -684,6 +690,39 @@ function describeSimIdSource(source) {
|
|
|
684
690
|
if (source === "saved") return "saved via `rnx use`";
|
|
685
691
|
return "primary fallback \u2014 no sim pinned";
|
|
686
692
|
}
|
|
693
|
+
var BRIDGE_VALUE_FLAGS_TABLE = [
|
|
694
|
+
{
|
|
695
|
+
names: ["--port", "-p"],
|
|
696
|
+
// naming the flag pins the world even when the value is missing or junk,
|
|
697
|
+
// so a later --base-url cannot quietly retarget the run to another shell.
|
|
698
|
+
apply: (state, value) => {
|
|
699
|
+
state.explicitPort = true;
|
|
700
|
+
if (value !== void 0) state.wsPort = Number(value);
|
|
701
|
+
}
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
names: ["--timeout"],
|
|
705
|
+
apply: (state, value) => {
|
|
706
|
+
if (value !== void 0) state.commandTimeoutMs = Number(value);
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
// `--sim` is the canonical target flag; `--session` / `--tab` are
|
|
711
|
+
// documented aliases (CLAUDE.md, the rnx agent skills, and engine docs all
|
|
712
|
+
// say `--session <id>`). without these aliases an agent following the docs
|
|
713
|
+
// would have `--session ef` silently ignored and get the *currently
|
|
714
|
+
// pinned* sim's tree instead — wrong-app data with no error.
|
|
715
|
+
names: ["--sim", "--session", "--tab"],
|
|
716
|
+
apply: (state, value) => {
|
|
717
|
+
if (value === void 0) return;
|
|
718
|
+
state.simId = value.trim() || void 0;
|
|
719
|
+
state.simIdSource = "flag";
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
];
|
|
723
|
+
var BRIDGE_VALUE_FLAGS = BRIDGE_VALUE_FLAGS_TABLE.flatMap(
|
|
724
|
+
(flag) => [...flag.names]
|
|
725
|
+
);
|
|
687
726
|
function createBridge(wsPort, opts = {}) {
|
|
688
727
|
let nextId = 1;
|
|
689
728
|
const commandTimeoutMs = opts.commandTimeoutMs ?? 15e3;
|
|
@@ -2769,10 +2808,8 @@ var import_path3 = __toESM(require("path"), 1);
|
|
|
2769
2808
|
var import_node_child_process = require("node:child_process");
|
|
2770
2809
|
var import_node_crypto2 = require("node:crypto");
|
|
2771
2810
|
var import_node_fs4 = __toESM(require("node:fs"), 1);
|
|
2772
|
-
var import_node_http = __toESM(require("node:http"), 1);
|
|
2773
2811
|
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
2774
2812
|
var import_node_url = require("node:url");
|
|
2775
|
-
var scheduledMetroOpens = /* @__PURE__ */ new Set();
|
|
2776
2813
|
function resolveRnxDesktopAppName(open, projectRoot) {
|
|
2777
2814
|
if (!open) return null;
|
|
2778
2815
|
if (typeof open === "object") {
|
|
@@ -2843,82 +2880,6 @@ function launchRnxDesktop(bundleUrl, appName) {
|
|
|
2843
2880
|
);
|
|
2844
2881
|
observeRnxDesktopLaunch(child, appName);
|
|
2845
2882
|
}
|
|
2846
|
-
function openRnxDesktopWhenMetroIsReady({
|
|
2847
|
-
port,
|
|
2848
|
-
bundleUrl,
|
|
2849
|
-
appName,
|
|
2850
|
-
projectRoot,
|
|
2851
|
-
serverId,
|
|
2852
|
-
intervalMs = 100,
|
|
2853
|
-
timeoutMs = 3e4,
|
|
2854
|
-
launch = launchRnxDesktop
|
|
2855
|
-
}) {
|
|
2856
|
-
const key = `${projectRoot}\0${port}`;
|
|
2857
|
-
if (scheduledMetroOpens.has(key)) return Promise.resolve(false);
|
|
2858
|
-
scheduledMetroOpens.add(key);
|
|
2859
|
-
const deadline = Date.now() + timeoutMs;
|
|
2860
|
-
return new Promise((resolve2) => {
|
|
2861
|
-
let finished = false;
|
|
2862
|
-
let retryTimer;
|
|
2863
|
-
const finish = (opened) => {
|
|
2864
|
-
if (finished) return;
|
|
2865
|
-
finished = true;
|
|
2866
|
-
clearTimeout(retryTimer);
|
|
2867
|
-
scheduledMetroOpens.delete(key);
|
|
2868
|
-
resolve2(opened);
|
|
2869
|
-
};
|
|
2870
|
-
const retry = () => {
|
|
2871
|
-
if (finished) return;
|
|
2872
|
-
if (Date.now() >= deadline) {
|
|
2873
|
-
console.error(
|
|
2874
|
-
`[rnx] could not open ${appName}: Metro did not become ready on port ${port}`
|
|
2875
|
-
);
|
|
2876
|
-
finish(false);
|
|
2877
|
-
return;
|
|
2878
|
-
}
|
|
2879
|
-
retryTimer = setTimeout(check, intervalMs);
|
|
2880
|
-
};
|
|
2881
|
-
const check = () => {
|
|
2882
|
-
const request = import_node_http.default.get(
|
|
2883
|
-
`http://127.0.0.1:${port}/__server-scan`,
|
|
2884
|
-
{ headers: { Accept: "application/json" } },
|
|
2885
|
-
(response) => {
|
|
2886
|
-
let body = "";
|
|
2887
|
-
response.setEncoding("utf8");
|
|
2888
|
-
response.on("data", (chunk) => {
|
|
2889
|
-
body = `${body}${chunk}`.slice(0, 65536);
|
|
2890
|
-
});
|
|
2891
|
-
response.once("end", () => {
|
|
2892
|
-
try {
|
|
2893
|
-
const scan = JSON.parse(body);
|
|
2894
|
-
const matches = response.statusCode === 200 && Array.isArray(scan) && scan.some((entry) => {
|
|
2895
|
-
if (!entry || typeof entry !== "object") return false;
|
|
2896
|
-
const scannedPort = Reflect.get(entry, "port");
|
|
2897
|
-
const projectName = Reflect.get(entry, "projectName");
|
|
2898
|
-
const scannedServerId = Reflect.get(entry, "rnxServerId");
|
|
2899
|
-
const scannedBundle = Reflect.get(entry, "bundleUrl");
|
|
2900
|
-
if (scannedPort !== port || projectName !== appName || scannedServerId !== serverId || typeof scannedBundle !== "string") {
|
|
2901
|
-
return false;
|
|
2902
|
-
}
|
|
2903
|
-
return new URL(scannedBundle).searchParams.get("rnxAppName") === appName;
|
|
2904
|
-
});
|
|
2905
|
-
if (matches) {
|
|
2906
|
-
launch(bundleUrl, appName);
|
|
2907
|
-
finish(true);
|
|
2908
|
-
return;
|
|
2909
|
-
}
|
|
2910
|
-
} catch {
|
|
2911
|
-
}
|
|
2912
|
-
retry();
|
|
2913
|
-
});
|
|
2914
|
-
}
|
|
2915
|
-
);
|
|
2916
|
-
request.setTimeout(Math.min(1e3, timeoutMs), () => request.destroy());
|
|
2917
|
-
request.once("error", retry);
|
|
2918
|
-
};
|
|
2919
|
-
check();
|
|
2920
|
-
});
|
|
2921
|
-
}
|
|
2922
2883
|
|
|
2923
2884
|
// src/host/replacement-module-handler.ts
|
|
2924
2885
|
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
@@ -3443,7 +3404,7 @@ function appendRNXModulePaths(result, graph, options, projectRoot) {
|
|
|
3443
3404
|
const dependencies = graph.dependencies;
|
|
3444
3405
|
const createModuleId = options.createModuleId;
|
|
3445
3406
|
if (!dependencies || !createModuleId) {
|
|
3446
|
-
|
|
3407
|
+
return result;
|
|
3447
3408
|
}
|
|
3448
3409
|
const modulePaths = {};
|
|
3449
3410
|
for (const module2 of dependencies.values()) {
|
|
@@ -3477,13 +3438,9 @@ function appendRNXModulePaths(result, graph, options, projectRoot) {
|
|
|
3477
3438
|
};
|
|
3478
3439
|
return typeof result === "string" ? appendRNXMetroModuleIdentityFooter(result, identity) : { ...result, code: appendRNXMetroModuleIdentityFooter(result.code, identity) };
|
|
3479
3440
|
}
|
|
3480
|
-
function withRNX(config
|
|
3481
|
-
if (!options.devServer && !options.open && !options.productionBundles && !options.developmentBundles) {
|
|
3482
|
-
return config;
|
|
3483
|
-
}
|
|
3441
|
+
function withRNX(config) {
|
|
3484
3442
|
const cfgProjectRoot = config.projectRoot || process.cwd();
|
|
3485
|
-
const
|
|
3486
|
-
const configuredBundleUrl = options.bundleUrl || "/index.bundle?platform=ios&dev=true&hot=true&minify=false";
|
|
3443
|
+
const configuredBundleUrl = "/index.bundle?platform=ios&dev=true&hot=true&minify=false";
|
|
3487
3444
|
const cfgServer = config.server;
|
|
3488
3445
|
const port = resolveMetroPort(cfgServer);
|
|
3489
3446
|
const metroServerId = (0, import_node_crypto4.randomUUID)();
|
|
@@ -3491,32 +3448,22 @@ function withRNX(config, options = {}) {
|
|
|
3491
3448
|
configuredBundleUrl,
|
|
3492
3449
|
`http://localhost:${port}`,
|
|
3493
3450
|
metroServerId,
|
|
3494
|
-
cfgProjectRoot
|
|
3495
|
-
appName
|
|
3451
|
+
cfgProjectRoot
|
|
3496
3452
|
);
|
|
3497
3453
|
const cfgSerializer = config.serializer;
|
|
3498
3454
|
const existingEnhance = cfgServer?.enhanceMiddleware;
|
|
3499
3455
|
const existingSerializer = cfgSerializer?.customSerializer;
|
|
3500
|
-
let
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
const result = await serializer(
|
|
3509
|
-
entryPoint,
|
|
3510
|
-
preModules,
|
|
3511
|
-
graph,
|
|
3512
|
-
serializerOptions
|
|
3513
|
-
);
|
|
3514
|
-
const dev = serializerOptions.dev;
|
|
3515
|
-
return dev === false && options.productionBundles === true || dev === true && options.developmentBundles === true ? appendRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot) : result;
|
|
3516
|
-
}
|
|
3456
|
+
let defaultSerializer;
|
|
3457
|
+
const serializerConfig = {
|
|
3458
|
+
serializer: {
|
|
3459
|
+
...cfgSerializer,
|
|
3460
|
+
customSerializer: async (entryPoint, preModules, graph, serializerOptions) => {
|
|
3461
|
+
const serializer = existingSerializer || (defaultSerializer ||= createMetroDefaultSerializer(cfgProjectRoot));
|
|
3462
|
+
const result = await serializer(entryPoint, preModules, graph, serializerOptions);
|
|
3463
|
+
return appendRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot);
|
|
3517
3464
|
}
|
|
3518
|
-
}
|
|
3519
|
-
}
|
|
3465
|
+
}
|
|
3466
|
+
};
|
|
3520
3467
|
const serverConfig = {
|
|
3521
3468
|
...cfgServer,
|
|
3522
3469
|
enhanceMiddleware: (metroMiddleware, metroServer) => {
|
|
@@ -3545,23 +3492,6 @@ function withRNX(config, options = {}) {
|
|
|
3545
3492
|
}
|
|
3546
3493
|
const url = req.url || "";
|
|
3547
3494
|
const pathname = url.split("?")[0];
|
|
3548
|
-
if (pathname === "/__server-scan") {
|
|
3549
|
-
const absoluteBundleUrl = bundleUrl.startsWith("http") ? bundleUrl : `http://localhost:${port}${bundleUrl}`;
|
|
3550
|
-
res.setHeader("content-type", "application/json");
|
|
3551
|
-
res.end(
|
|
3552
|
-
JSON.stringify([
|
|
3553
|
-
{
|
|
3554
|
-
port,
|
|
3555
|
-
framework: "metro",
|
|
3556
|
-
rnxServerId: metroServerId,
|
|
3557
|
-
bundleUrl: absoluteBundleUrl,
|
|
3558
|
-
...appName ? { projectName: appName } : {},
|
|
3559
|
-
lastSeen: Date.now()
|
|
3560
|
-
}
|
|
3561
|
-
])
|
|
3562
|
-
);
|
|
3563
|
-
return;
|
|
3564
|
-
}
|
|
3565
3495
|
const runtimeRoot = resolveRuntimeRootForRequestHost(req.headers?.host);
|
|
3566
3496
|
if (!runtimeRoot) {
|
|
3567
3497
|
if (pathname === prefix || pathname === prefix + "/") {
|
|
@@ -3594,10 +3524,8 @@ function withRNX(config, options = {}) {
|
|
|
3594
3524
|
if (!ext) {
|
|
3595
3525
|
const htmlPath = import_path4.default.join(runtimeRoot, "index.html");
|
|
3596
3526
|
let html = import_fs5.default.readFileSync(htmlPath, "utf8");
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
`<script>(function(){var u=new URL(location.href);if(!u.searchParams.has('bundle'))u.searchParams.set('bundle',${JSON.stringify(bundleUrl)});history.replaceState(null,'','${prefix}/'+u.search)})()</script></head>`
|
|
3600
|
-
);
|
|
3527
|
+
const script = `<script>(function(){var u=new URL(location.href);if(!u.searchParams.has('bundle'))u.searchParams.set('bundle',${JSON.stringify(bundleUrl)});history.replaceState(null,'','${prefix}/'+u.search)})()</script>`;
|
|
3528
|
+
html = html.includes("</head>") ? html.replace("</head>", `${script}</head>`) : `${html}${script}`;
|
|
3601
3529
|
res.setHeader("content-type", "text/html");
|
|
3602
3530
|
res.end(html);
|
|
3603
3531
|
return;
|
|
@@ -3610,19 +3538,10 @@ function withRNX(config, options = {}) {
|
|
|
3610
3538
|
return server;
|
|
3611
3539
|
}
|
|
3612
3540
|
};
|
|
3613
|
-
if (appName && !process.env.CI && !process.env.RNX_NO_OPEN) {
|
|
3614
|
-
void openRnxDesktopWhenMetroIsReady({
|
|
3615
|
-
port,
|
|
3616
|
-
bundleUrl: resolveRnxDesktopLaunchTarget(port, bundleUrl),
|
|
3617
|
-
appName,
|
|
3618
|
-
projectRoot: cfgProjectRoot,
|
|
3619
|
-
serverId: metroServerId
|
|
3620
|
-
});
|
|
3621
|
-
}
|
|
3622
3541
|
return {
|
|
3623
3542
|
...config,
|
|
3624
|
-
...
|
|
3625
|
-
|
|
3543
|
+
...serializerConfig,
|
|
3544
|
+
server: serverConfig
|
|
3626
3545
|
};
|
|
3627
3546
|
}
|
|
3628
3547
|
function resolveMetroPort(server) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.433 | (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 __defProp = Object.defineProperty;
|
package/dist-lib/menu.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.433 | (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 __defProp = Object.defineProperty;
|
package/dist-lib/menu.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.433 | (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 __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.433 | (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 __defProp = Object.defineProperty;
|