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/skills.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;
|
|
@@ -21683,6 +21683,197 @@ var init_metro_production_bundle = __esm({
|
|
|
21683
21683
|
}
|
|
21684
21684
|
});
|
|
21685
21685
|
|
|
21686
|
+
// src/auth/shared-session.ts
|
|
21687
|
+
function sharedDesktopAuthAccounts(user) {
|
|
21688
|
+
return [
|
|
21689
|
+
...user?.personalAccountId ? [{ id: user.personalAccountId, name: "Personal" }] : [],
|
|
21690
|
+
...(user?.teams ?? []).map((team) => ({ id: team.id, name: team.name }))
|
|
21691
|
+
];
|
|
21692
|
+
}
|
|
21693
|
+
function getBaseDir() {
|
|
21694
|
+
const explicit = process.env[SESSION_FILE_ENV];
|
|
21695
|
+
if (explicit?.trim()) {
|
|
21696
|
+
return (0, import_node_path14.dirname)((0, import_node_path14.resolve)(explicit));
|
|
21697
|
+
}
|
|
21698
|
+
return electronUserDataDir();
|
|
21699
|
+
}
|
|
21700
|
+
function getSharedDesktopAuthFilePath() {
|
|
21701
|
+
const explicit = process.env[SESSION_FILE_ENV];
|
|
21702
|
+
if (explicit?.trim()) return (0, import_node_path14.resolve)(explicit);
|
|
21703
|
+
return (0, import_node_path14.join)(getBaseDir(), "desktop-auth.json");
|
|
21704
|
+
}
|
|
21705
|
+
function normalizeUser(input) {
|
|
21706
|
+
if (!input || typeof input !== "object") return null;
|
|
21707
|
+
const value = input;
|
|
21708
|
+
if (typeof value.id !== "string" || !value.id.trim()) return null;
|
|
21709
|
+
return {
|
|
21710
|
+
id: value.id.trim(),
|
|
21711
|
+
name: typeof value.name === "string" ? value.name : void 0,
|
|
21712
|
+
email: typeof value.email === "string" ? value.email : void 0,
|
|
21713
|
+
image: typeof value.image === "string" ? value.image : void 0,
|
|
21714
|
+
githubUsername: typeof value.githubUsername === "string" ? value.githubUsername : void 0,
|
|
21715
|
+
personalAccountId: typeof value.personalAccountId === "string" && value.personalAccountId.trim() ? value.personalAccountId.trim() : void 0,
|
|
21716
|
+
isAdmin: value.isAdmin === true,
|
|
21717
|
+
teams: Array.isArray(value.teams) ? value.teams.map((team) => {
|
|
21718
|
+
if (!team || typeof team !== "object") return null;
|
|
21719
|
+
const t = team;
|
|
21720
|
+
if (typeof t.id !== "string" || typeof t.name !== "string") return null;
|
|
21721
|
+
return {
|
|
21722
|
+
id: t.id,
|
|
21723
|
+
name: t.name,
|
|
21724
|
+
role: t.role === "owner" ? "owner" : "member",
|
|
21725
|
+
githubOrg: typeof t.githubOrg === "string" ? t.githubOrg : null
|
|
21726
|
+
};
|
|
21727
|
+
}).filter((team) => !!team) : void 0
|
|
21728
|
+
};
|
|
21729
|
+
}
|
|
21730
|
+
function normalizeSession(input) {
|
|
21731
|
+
if (!input || typeof input !== "object") return null;
|
|
21732
|
+
const value = input;
|
|
21733
|
+
if (value.version !== SESSION_VERSION) return null;
|
|
21734
|
+
if (typeof value.token !== "string" || !value.token.trim()) return null;
|
|
21735
|
+
const origin = typeof value.origin === "string" && value.origin.trim() ? value.origin.trim() : DEFAULT_ORIGIN;
|
|
21736
|
+
const source = value.source === "cli" || value.source === "electron" || value.source === "browser" || value.source === "unknown" ? value.source : "unknown";
|
|
21737
|
+
const updatedAt = typeof value.updatedAt === "string" && value.updatedAt ? value.updatedAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
21738
|
+
const validatedAt = typeof value.validatedAt === "string" && value.validatedAt ? value.validatedAt : void 0;
|
|
21739
|
+
const accountId = typeof value.accountId === "string" && value.accountId.trim() ? value.accountId.trim() : void 0;
|
|
21740
|
+
return {
|
|
21741
|
+
version: SESSION_VERSION,
|
|
21742
|
+
token: value.token.trim(),
|
|
21743
|
+
user: normalizeUser(value.user),
|
|
21744
|
+
origin,
|
|
21745
|
+
source,
|
|
21746
|
+
updatedAt,
|
|
21747
|
+
validatedAt,
|
|
21748
|
+
accountId
|
|
21749
|
+
};
|
|
21750
|
+
}
|
|
21751
|
+
function readSharedDesktopAuthSession() {
|
|
21752
|
+
const filepath = getSharedDesktopAuthFilePath();
|
|
21753
|
+
if (!(0, import_node_fs13.existsSync)(filepath)) return null;
|
|
21754
|
+
try {
|
|
21755
|
+
const parsed = JSON.parse((0, import_node_fs13.readFileSync)(filepath, "utf8"));
|
|
21756
|
+
const normalized = normalizeSession(parsed);
|
|
21757
|
+
if (!normalized) {
|
|
21758
|
+
(0, import_node_fs13.rmSync)(filepath, { force: true });
|
|
21759
|
+
return null;
|
|
21760
|
+
}
|
|
21761
|
+
return normalized;
|
|
21762
|
+
} catch {
|
|
21763
|
+
(0, import_node_fs13.rmSync)(filepath, { force: true });
|
|
21764
|
+
return null;
|
|
21765
|
+
}
|
|
21766
|
+
}
|
|
21767
|
+
var import_node_fs13, import_node_path14, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
|
|
21768
|
+
var init_shared_session = __esm({
|
|
21769
|
+
"src/auth/shared-session.ts"() {
|
|
21770
|
+
"use strict";
|
|
21771
|
+
import_node_fs13 = require("node:fs");
|
|
21772
|
+
import_node_path14 = require("node:path");
|
|
21773
|
+
init_home_paths();
|
|
21774
|
+
SESSION_VERSION = 1;
|
|
21775
|
+
SESSION_FILE_ENV = "SOOTSIM_SHARED_AUTH_FILE";
|
|
21776
|
+
DEFAULT_ORIGIN = "https://contrast.dev";
|
|
21777
|
+
}
|
|
21778
|
+
});
|
|
21779
|
+
|
|
21780
|
+
// cli/run-rnx.ts
|
|
21781
|
+
function rethrowIfExit(error) {
|
|
21782
|
+
if (error instanceof RnxExit) throw error;
|
|
21783
|
+
}
|
|
21784
|
+
function rnxExit(code) {
|
|
21785
|
+
throw new RnxExit(code);
|
|
21786
|
+
}
|
|
21787
|
+
var import_node_async_hooks, RnxExit, sinks;
|
|
21788
|
+
var init_run_rnx = __esm({
|
|
21789
|
+
"cli/run-rnx.ts"() {
|
|
21790
|
+
"use strict";
|
|
21791
|
+
import_node_async_hooks = require("node:async_hooks");
|
|
21792
|
+
RnxExit = class extends Error {
|
|
21793
|
+
code;
|
|
21794
|
+
constructor(code) {
|
|
21795
|
+
super(`rnx exited with code ${code}`);
|
|
21796
|
+
this.name = "RnxExit";
|
|
21797
|
+
this.code = code;
|
|
21798
|
+
}
|
|
21799
|
+
};
|
|
21800
|
+
sinks = new import_node_async_hooks.AsyncLocalStorage();
|
|
21801
|
+
}
|
|
21802
|
+
});
|
|
21803
|
+
|
|
21804
|
+
// cli/auth.ts
|
|
21805
|
+
function looksLikeGitHubToken(token) {
|
|
21806
|
+
return Boolean(
|
|
21807
|
+
token && token.length >= 20 && GITHUB_TOKEN_PREFIXES.some((prefix) => token.startsWith(prefix))
|
|
21808
|
+
);
|
|
21809
|
+
}
|
|
21810
|
+
function resolveGitHubActionsAuth() {
|
|
21811
|
+
const contrastRunnerToken = process.env.CONTRAST_INSTALLATION_TOKEN?.trim();
|
|
21812
|
+
const githubActionsToken = process.env.GITHUB_TOKEN?.trim();
|
|
21813
|
+
const token = contrastRunnerToken || githubActionsToken;
|
|
21814
|
+
if (!looksLikeGitHubToken(token)) return null;
|
|
21815
|
+
const repoSlug = (process.env.CONTRAST_REPO || process.env.GITHUB_REPOSITORY || "").trim();
|
|
21816
|
+
if (!repoSlug) return null;
|
|
21817
|
+
const [owner, repo] = repoSlug.includes("/") ? repoSlug.split("/", 2) : [null, null];
|
|
21818
|
+
const repositoryId = (process.env.CONTRAST_REPO_ID || process.env.GITHUB_REPOSITORY_ID || "").trim();
|
|
21819
|
+
const installationId = (process.env.CONTRAST_INSTALLATION_ID || process.env.GITHUB_APP_INSTALLATION_ID || "").trim();
|
|
21820
|
+
return {
|
|
21821
|
+
kind: "github",
|
|
21822
|
+
token,
|
|
21823
|
+
repoId: repoSlug,
|
|
21824
|
+
repositoryId: repositoryId || null,
|
|
21825
|
+
owner: owner || null,
|
|
21826
|
+
repo: repo || null,
|
|
21827
|
+
installationId: installationId || null,
|
|
21828
|
+
source: contrastRunnerToken ? "contrast-runner" : "github-actions"
|
|
21829
|
+
};
|
|
21830
|
+
}
|
|
21831
|
+
function isCliApiKeySecret(secret) {
|
|
21832
|
+
return secret.startsWith("sk_rnx_");
|
|
21833
|
+
}
|
|
21834
|
+
function readApiKeyFromEnv() {
|
|
21835
|
+
const envName = "RNX_API_KEY";
|
|
21836
|
+
const secret = process.env[envName]?.trim();
|
|
21837
|
+
return secret && isCliApiKeySecret(secret) ? { secret, envName } : null;
|
|
21838
|
+
}
|
|
21839
|
+
function resolveCliAuth() {
|
|
21840
|
+
const envKey = readApiKeyFromEnv();
|
|
21841
|
+
if (envKey) {
|
|
21842
|
+
return {
|
|
21843
|
+
kind: "api-key",
|
|
21844
|
+
secret: envKey.secret,
|
|
21845
|
+
source: "env",
|
|
21846
|
+
envName: envKey.envName
|
|
21847
|
+
};
|
|
21848
|
+
}
|
|
21849
|
+
const githubAuth = resolveGitHubActionsAuth();
|
|
21850
|
+
if (githubAuth) return githubAuth;
|
|
21851
|
+
const session = readSharedDesktopAuthSession();
|
|
21852
|
+
if (session?.token) {
|
|
21853
|
+
const accounts = sharedDesktopAuthAccounts(session.user);
|
|
21854
|
+
return {
|
|
21855
|
+
kind: "session",
|
|
21856
|
+
token: session.token,
|
|
21857
|
+
origin: session.origin,
|
|
21858
|
+
accountId: session.accountId ?? (accounts.length === 1 ? accounts[0]?.id ?? null : null)
|
|
21859
|
+
};
|
|
21860
|
+
}
|
|
21861
|
+
return null;
|
|
21862
|
+
}
|
|
21863
|
+
function authHeaderValue(auth) {
|
|
21864
|
+
return auth.kind === "api-key" ? `Bearer ${auth.secret}` : `Bearer ${auth.token}`;
|
|
21865
|
+
}
|
|
21866
|
+
var GITHUB_TOKEN_PREFIXES, CHOOSE_ACCOUNT_HINT;
|
|
21867
|
+
var init_auth = __esm({
|
|
21868
|
+
"cli/auth.ts"() {
|
|
21869
|
+
"use strict";
|
|
21870
|
+
init_shared_session();
|
|
21871
|
+
init_run_rnx();
|
|
21872
|
+
GITHUB_TOKEN_PREFIXES = ["ghs_", "ghp_", "gho_", "ghu_", "github_pat_"];
|
|
21873
|
+
CHOOSE_ACCOUNT_HINT = "this sign-in belongs to several accounts; run `rnx login --account <name>` to choose the one to bill";
|
|
21874
|
+
}
|
|
21875
|
+
});
|
|
21876
|
+
|
|
21686
21877
|
// cli/cloud-session.ts
|
|
21687
21878
|
function isRecord3(value) {
|
|
21688
21879
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -21692,13 +21883,13 @@ function normalizeCloudOrigin(source) {
|
|
|
21692
21883
|
try {
|
|
21693
21884
|
parsed = new URL(source);
|
|
21694
21885
|
} catch {
|
|
21695
|
-
throw new Error(`invalid
|
|
21886
|
+
throw new Error(`invalid remote simulator origin: ${source}`);
|
|
21696
21887
|
}
|
|
21697
21888
|
if (parsed.protocol !== "https:" && parsed.protocol !== "http:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
21698
|
-
throw new Error(`
|
|
21889
|
+
throw new Error(`remote simulator origin must be an HTTP(S) origin: ${source}`);
|
|
21699
21890
|
}
|
|
21700
21891
|
if (parsed.protocol === "http:" && !isLoopbackHost(parsed.hostname)) {
|
|
21701
|
-
throw new Error(`
|
|
21892
|
+
throw new Error(`remote simulator origin requires HTTPS outside loopback: ${source}`);
|
|
21702
21893
|
}
|
|
21703
21894
|
return parsed.origin;
|
|
21704
21895
|
}
|
|
@@ -21768,23 +21959,37 @@ var init_cloud_session = __esm({
|
|
|
21768
21959
|
}
|
|
21769
21960
|
});
|
|
21770
21961
|
|
|
21962
|
+
// cli/commands/detect.ts
|
|
21963
|
+
var init_detect = __esm({
|
|
21964
|
+
"cli/commands/detect.ts"() {
|
|
21965
|
+
"use strict";
|
|
21966
|
+
}
|
|
21967
|
+
});
|
|
21968
|
+
|
|
21771
21969
|
// cli/cloud-client.ts
|
|
21772
21970
|
function isRecord4(value) {
|
|
21773
21971
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
21774
21972
|
}
|
|
21775
|
-
function
|
|
21776
|
-
|
|
21777
|
-
|
|
21778
|
-
|
|
21779
|
-
|
|
21780
|
-
|
|
21781
|
-
|
|
21782
|
-
|
|
21783
|
-
|
|
21784
|
-
|
|
21973
|
+
function failureSentence(text) {
|
|
21974
|
+
let parsed;
|
|
21975
|
+
try {
|
|
21976
|
+
parsed = JSON.parse(text);
|
|
21977
|
+
} catch {
|
|
21978
|
+
return null;
|
|
21979
|
+
}
|
|
21980
|
+
if (!isRecord4(parsed)) return null;
|
|
21981
|
+
if (isRecord4(parsed.error) && typeof parsed.error.message === "string") {
|
|
21982
|
+
return parsed.error.message;
|
|
21785
21983
|
}
|
|
21984
|
+
if (typeof parsed.message === "string") return parsed.message;
|
|
21985
|
+
if (typeof parsed.error === "string") return parsed.error;
|
|
21986
|
+
return null;
|
|
21987
|
+
}
|
|
21988
|
+
function responseError(status, text) {
|
|
21989
|
+
const parsed = text ? failureSentence(text) : null;
|
|
21990
|
+
const sentence = parsed && ACCOUNT_CHOICE_REFUSALS.has(parsed) ? CHOOSE_ACCOUNT_HINT : parsed;
|
|
21786
21991
|
return new Error(
|
|
21787
|
-
`
|
|
21992
|
+
`remote simulator request failed (${status})${sentence ? `: ${sentence}` : text.trim() ? `: ${text.trim()}` : ""}`
|
|
21788
21993
|
);
|
|
21789
21994
|
}
|
|
21790
21995
|
function resolveCloudSessionForParsed(parsed) {
|
|
@@ -21792,7 +21997,7 @@ function resolveCloudSessionForParsed(parsed) {
|
|
|
21792
21997
|
if (!session) return null;
|
|
21793
21998
|
if (parsed.simIdSource === "flag" && parsed.simId !== session.simId) {
|
|
21794
21999
|
throw new Error(
|
|
21795
|
-
`this shell is connected to
|
|
22000
|
+
`this shell is connected to remote simulator ${session.simId}; ${parsed.simId ? `--sim ${parsed.simId}` : "the requested simulator"} is not available in this shell`
|
|
21796
22001
|
);
|
|
21797
22002
|
}
|
|
21798
22003
|
return session;
|
|
@@ -21803,13 +22008,15 @@ function cloudCommand(command) {
|
|
|
21803
22008
|
if (key !== "id" && key !== "simId") clean[key] = value;
|
|
21804
22009
|
}
|
|
21805
22010
|
if (isRnxCloudCommandType(command.type)) return clean;
|
|
21806
|
-
throw new Error(
|
|
22011
|
+
throw new Error(
|
|
22012
|
+
`a remote simulator does not support bridge command type ${command.type}`
|
|
22013
|
+
);
|
|
21807
22014
|
}
|
|
21808
22015
|
function createCloudBridgeForParsed(parsed) {
|
|
21809
22016
|
const session = resolveCloudSessionForParsed(parsed);
|
|
21810
22017
|
return session ? new CloudBridge(session) : null;
|
|
21811
22018
|
}
|
|
21812
|
-
var import_node_crypto5, DEFAULT_RNX_CLOUD_ORIGIN, CloudBridge;
|
|
22019
|
+
var import_node_crypto5, DEFAULT_RNX_CLOUD_ORIGIN, MAX_RNX_CLOUD_BUNDLE_BYTES, WARN_ARTIFACT_BYTES, ACCOUNT_CHOICE_REFUSALS, CloudBridge;
|
|
21813
22020
|
var init_cloud_client = __esm({
|
|
21814
22021
|
"cli/cloud-client.ts"() {
|
|
21815
22022
|
"use strict";
|
|
@@ -21819,8 +22026,16 @@ var init_cloud_client = __esm({
|
|
|
21819
22026
|
init_cloud_contract();
|
|
21820
22027
|
init_metro_production_bundle();
|
|
21821
22028
|
init_public_brand();
|
|
22029
|
+
init_auth();
|
|
21822
22030
|
init_cloud_session();
|
|
22031
|
+
init_detect();
|
|
21823
22032
|
DEFAULT_RNX_CLOUD_ORIGIN = rnxPublicBrand.origin;
|
|
22033
|
+
MAX_RNX_CLOUD_BUNDLE_BYTES = RNX_CLOUD_MAX_ARTIFACT_BYTES;
|
|
22034
|
+
WARN_ARTIFACT_BYTES = Math.floor(MAX_RNX_CLOUD_BUNDLE_BYTES * 0.8);
|
|
22035
|
+
ACCOUNT_CHOICE_REFUSALS = /* @__PURE__ */ new Set([
|
|
22036
|
+
"accountId is required",
|
|
22037
|
+
"you do not have access to this account"
|
|
22038
|
+
]);
|
|
21824
22039
|
CloudBridge = class {
|
|
21825
22040
|
constructor(session) {
|
|
21826
22041
|
this.session = session;
|
|
@@ -21848,7 +22063,7 @@ var init_cloud_client = __esm({
|
|
|
21848
22063
|
);
|
|
21849
22064
|
} catch (error) {
|
|
21850
22065
|
throw new Error(
|
|
21851
|
-
`could not reach
|
|
22066
|
+
`could not reach the remote simulator at ${this.session.apiOrigin}: ${error instanceof Error ? error.message : String(error)}`
|
|
21852
22067
|
);
|
|
21853
22068
|
}
|
|
21854
22069
|
const text = await response.text();
|
|
@@ -21857,30 +22072,34 @@ var init_cloud_client = __esm({
|
|
|
21857
22072
|
try {
|
|
21858
22073
|
parsed = JSON.parse(text);
|
|
21859
22074
|
} catch {
|
|
21860
|
-
throw new Error("
|
|
22075
|
+
throw new Error("remote simulator command returned unreadable JSON");
|
|
21861
22076
|
}
|
|
21862
22077
|
if (!isRecord4(parsed) || parsed.id !== body.id) {
|
|
21863
|
-
throw new Error("
|
|
22078
|
+
throw new Error("remote simulator command returned an invalid command receipt");
|
|
21864
22079
|
}
|
|
21865
22080
|
if (typeof parsed.error === "string" && parsed.error) throw new Error(parsed.error);
|
|
21866
22081
|
if (!Object.hasOwn(parsed, "result")) {
|
|
21867
|
-
throw new Error("
|
|
22082
|
+
throw new Error("remote simulator command receipt has no result");
|
|
21868
22083
|
}
|
|
21869
22084
|
return parsed.result;
|
|
21870
22085
|
}
|
|
21871
22086
|
listSims() {
|
|
21872
|
-
return Promise.reject(new Error("RNX Cloud does not expose a local simulator list"));
|
|
21873
|
-
}
|
|
21874
|
-
focusSim() {
|
|
21875
22087
|
return Promise.reject(
|
|
21876
|
-
new Error("
|
|
22088
|
+
new Error("a remote simulator does not expose a local simulator list")
|
|
21877
22089
|
);
|
|
21878
22090
|
}
|
|
22091
|
+
focusSim() {
|
|
22092
|
+
return Promise.reject(new Error("remote simulators have no browser window to focus"));
|
|
22093
|
+
}
|
|
21879
22094
|
closeSim() {
|
|
21880
|
-
return Promise.reject(
|
|
22095
|
+
return Promise.reject(
|
|
22096
|
+
new Error("remote simulator close uses the simulator DELETE route")
|
|
22097
|
+
);
|
|
21881
22098
|
}
|
|
21882
22099
|
claim() {
|
|
21883
|
-
return Promise.reject(
|
|
22100
|
+
return Promise.reject(
|
|
22101
|
+
new Error("remote simulator claim uses the simulator claim route")
|
|
22102
|
+
);
|
|
21884
22103
|
}
|
|
21885
22104
|
close() {
|
|
21886
22105
|
}
|
|
@@ -22049,31 +22268,31 @@ var init_parent_pid = __esm({
|
|
|
22049
22268
|
|
|
22050
22269
|
// cli/secure-file.ts
|
|
22051
22270
|
function writeSecureJsonAtomic(filepath, value) {
|
|
22052
|
-
(0,
|
|
22271
|
+
(0, import_node_fs14.mkdirSync)((0, import_node_path15.dirname)(filepath), { recursive: true });
|
|
22053
22272
|
const temporary = `${filepath}.tmp-${process.pid}-${(0, import_node_crypto6.randomUUID)()}`;
|
|
22054
22273
|
let descriptor = null;
|
|
22055
22274
|
try {
|
|
22056
|
-
descriptor = (0,
|
|
22057
|
-
(0,
|
|
22058
|
-
(0,
|
|
22275
|
+
descriptor = (0, import_node_fs14.openSync)(temporary, "wx", 384);
|
|
22276
|
+
(0, import_node_fs14.fchmodSync)(descriptor, 384);
|
|
22277
|
+
(0, import_node_fs14.writeFileSync)(descriptor, `${JSON.stringify(value, null, 2)}
|
|
22059
22278
|
`);
|
|
22060
|
-
(0,
|
|
22061
|
-
(0,
|
|
22279
|
+
(0, import_node_fs14.fsyncSync)(descriptor);
|
|
22280
|
+
(0, import_node_fs14.closeSync)(descriptor);
|
|
22062
22281
|
descriptor = null;
|
|
22063
|
-
(0,
|
|
22282
|
+
(0, import_node_fs14.renameSync)(temporary, filepath);
|
|
22064
22283
|
} catch (error) {
|
|
22065
|
-
if (descriptor !== null) (0,
|
|
22066
|
-
(0,
|
|
22284
|
+
if (descriptor !== null) (0, import_node_fs14.closeSync)(descriptor);
|
|
22285
|
+
(0, import_node_fs14.rmSync)(temporary, { force: true });
|
|
22067
22286
|
throw error;
|
|
22068
22287
|
}
|
|
22069
22288
|
}
|
|
22070
|
-
var import_node_crypto6,
|
|
22289
|
+
var import_node_crypto6, import_node_fs14, import_node_path15;
|
|
22071
22290
|
var init_secure_file = __esm({
|
|
22072
22291
|
"cli/secure-file.ts"() {
|
|
22073
22292
|
"use strict";
|
|
22074
22293
|
import_node_crypto6 = require("node:crypto");
|
|
22075
|
-
|
|
22076
|
-
|
|
22294
|
+
import_node_fs14 = require("node:fs");
|
|
22295
|
+
import_node_path15 = require("node:path");
|
|
22077
22296
|
}
|
|
22078
22297
|
});
|
|
22079
22298
|
|
|
@@ -22220,6 +22439,7 @@ var init_current_sim = __esm({
|
|
|
22220
22439
|
// cli/ws-bridge.ts
|
|
22221
22440
|
var ws_bridge_exports = {};
|
|
22222
22441
|
__export(ws_bridge_exports, {
|
|
22442
|
+
BRIDGE_VALUE_FLAGS: () => BRIDGE_VALUE_FLAGS,
|
|
22223
22443
|
BridgeSimLockedError: () => BridgeSimLockedError,
|
|
22224
22444
|
RNX_PLACEMENT_ENV: () => RNX_PLACEMENT_ENV,
|
|
22225
22445
|
bridgePortForShellBaseUrl: () => bridgePortForShellBaseUrl,
|
|
@@ -22232,6 +22452,7 @@ __export(ws_bridge_exports, {
|
|
|
22232
22452
|
evalInBridge: () => evalInBridge,
|
|
22233
22453
|
parseBridgeCliArgs: () => parseBridgeCliArgs,
|
|
22234
22454
|
printBridgeWorldNotice: () => printBridgeWorldNotice,
|
|
22455
|
+
resolveBridgePortForPin: () => resolveBridgePortForPin,
|
|
22235
22456
|
resolveBridgeWorld: () => resolveBridgeWorld,
|
|
22236
22457
|
resolveDefaultBridgePort: () => resolveDefaultBridgePort,
|
|
22237
22458
|
resolvePlacement: () => resolvePlacement,
|
|
@@ -22247,17 +22468,17 @@ function liveDevBridgeLockfiles() {
|
|
|
22247
22468
|
return readDevBridgeLockfiles().filter((lockfile) => isDevBridgeLockfileFresh(lockfile));
|
|
22248
22469
|
}
|
|
22249
22470
|
function checkoutRoot(cwd) {
|
|
22250
|
-
let current =
|
|
22471
|
+
let current = import_node_path16.default.resolve(cwd);
|
|
22251
22472
|
while (true) {
|
|
22252
|
-
if (
|
|
22253
|
-
const parent =
|
|
22473
|
+
if (import_node_fs15.default.existsSync(import_node_path16.default.join(current, ".git"))) return current;
|
|
22474
|
+
const parent = import_node_path16.default.dirname(current);
|
|
22254
22475
|
if (parent === current) return null;
|
|
22255
22476
|
current = parent;
|
|
22256
22477
|
}
|
|
22257
22478
|
}
|
|
22258
22479
|
function pathContains(parent, child) {
|
|
22259
|
-
const relative =
|
|
22260
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
22480
|
+
const relative = import_node_path16.default.relative(parent, child);
|
|
22481
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${import_node_path16.default.sep}`) && !import_node_path16.default.isAbsolute(relative);
|
|
22261
22482
|
}
|
|
22262
22483
|
function resolveDefaultDevBridgeLockfile() {
|
|
22263
22484
|
const lockfiles = liveDevBridgeLockfiles();
|
|
@@ -22360,6 +22581,21 @@ function bridgePortForShellBaseUrl(baseUrl) {
|
|
|
22360
22581
|
}
|
|
22361
22582
|
return null;
|
|
22362
22583
|
}
|
|
22584
|
+
function resolveBridgePortForPin(pin) {
|
|
22585
|
+
const served = bridgePortForShellBaseUrl(pin.baseUrl);
|
|
22586
|
+
if (served === null) {
|
|
22587
|
+
if (pin.explicitPort) return { port: pin.wsPort };
|
|
22588
|
+
return {
|
|
22589
|
+
error: `no live rnx world serves ${pin.baseUrl} \u2014 start that shell first, or name its bridge with --port <port>`
|
|
22590
|
+
};
|
|
22591
|
+
}
|
|
22592
|
+
if (pin.explicitPort && pin.wsPort !== served) {
|
|
22593
|
+
return {
|
|
22594
|
+
error: `--base-url ${pin.baseUrl} belongs to bridge port ${served}, but --port ${pin.wsPort} names another world`
|
|
22595
|
+
};
|
|
22596
|
+
}
|
|
22597
|
+
return { port: served };
|
|
22598
|
+
}
|
|
22363
22599
|
function resolveDefaultBridgePort() {
|
|
22364
22600
|
return resolveBridgeWorld().bridgePort;
|
|
22365
22601
|
}
|
|
@@ -22380,57 +22616,33 @@ function describeSimIdSource(source) {
|
|
|
22380
22616
|
}
|
|
22381
22617
|
function parseBridgeCliArgs(args, opts = {}) {
|
|
22382
22618
|
const flagIndices = /* @__PURE__ */ new Set();
|
|
22383
|
-
|
|
22384
|
-
|
|
22385
|
-
|
|
22386
|
-
|
|
22387
|
-
|
|
22619
|
+
const state = {
|
|
22620
|
+
wsPort: opts.port ?? resolveDefaultBridgePort(),
|
|
22621
|
+
explicitPort: opts.port !== void 0,
|
|
22622
|
+
commandTimeoutMs: opts.commandTimeoutMs ?? 15e3,
|
|
22623
|
+
simId: void 0,
|
|
22624
|
+
simIdSource: "none"
|
|
22625
|
+
};
|
|
22388
22626
|
const stripBooleanFlags = new Set(opts.stripBooleanFlags ?? []);
|
|
22389
22627
|
const stripValueFlags = new Set(opts.stripValueFlags ?? []);
|
|
22390
22628
|
for (let i = 0; i < args.length; i++) {
|
|
22391
22629
|
const arg = args[i];
|
|
22392
|
-
|
|
22393
|
-
|
|
22394
|
-
|
|
22395
|
-
|
|
22396
|
-
flagIndices.add(i + 1);
|
|
22397
|
-
wsPort = Number(args[i + 1]);
|
|
22398
|
-
}
|
|
22399
|
-
i++;
|
|
22400
|
-
continue;
|
|
22401
|
-
}
|
|
22402
|
-
if (arg.startsWith("--port=")) {
|
|
22403
|
-
flagIndices.add(i);
|
|
22404
|
-
explicitPort = true;
|
|
22405
|
-
wsPort = Number(arg.slice("--port=".length));
|
|
22406
|
-
continue;
|
|
22407
|
-
}
|
|
22408
|
-
if (arg === "--timeout") {
|
|
22409
|
-
flagIndices.add(i);
|
|
22410
|
-
if (i + 1 < args.length) {
|
|
22411
|
-
flagIndices.add(i + 1);
|
|
22412
|
-
commandTimeoutMs = Number(args[i + 1]);
|
|
22413
|
-
}
|
|
22414
|
-
i++;
|
|
22415
|
-
continue;
|
|
22416
|
-
}
|
|
22417
|
-
if (arg === "--sim" || arg === "--session" || arg === "--tab") {
|
|
22630
|
+
const valueFlag = BRIDGE_VALUE_FLAGS_TABLE.find(
|
|
22631
|
+
(flag) => flag.names.some((name2) => arg === name2 || arg.startsWith(`${name2}=`))
|
|
22632
|
+
);
|
|
22633
|
+
if (valueFlag) {
|
|
22418
22634
|
flagIndices.add(i);
|
|
22419
|
-
|
|
22420
|
-
|
|
22421
|
-
|
|
22422
|
-
|
|
22635
|
+
const inline = valueFlag.names.find((name2) => arg.startsWith(`${name2}=`));
|
|
22636
|
+
if (inline) {
|
|
22637
|
+
valueFlag.apply(state, arg.slice(inline.length + 1));
|
|
22638
|
+
continue;
|
|
22423
22639
|
}
|
|
22640
|
+
const value = i + 1 < args.length ? args[i + 1] : void 0;
|
|
22641
|
+
if (value !== void 0) flagIndices.add(i + 1);
|
|
22642
|
+
valueFlag.apply(state, value);
|
|
22424
22643
|
i++;
|
|
22425
22644
|
continue;
|
|
22426
22645
|
}
|
|
22427
|
-
const simEq = arg.startsWith("--sim=") ? arg.slice("--sim=".length) : arg.startsWith("--session=") ? arg.slice("--session=".length) : arg.startsWith("--tab=") ? arg.slice("--tab=".length) : void 0;
|
|
22428
|
-
if (simEq !== void 0) {
|
|
22429
|
-
flagIndices.add(i);
|
|
22430
|
-
simId = simEq.trim() || void 0;
|
|
22431
|
-
simIdSource = "flag";
|
|
22432
|
-
continue;
|
|
22433
|
-
}
|
|
22434
22646
|
if (stripBooleanFlags.has(arg)) {
|
|
22435
22647
|
flagIndices.add(i);
|
|
22436
22648
|
continue;
|
|
@@ -22443,20 +22655,20 @@ function parseBridgeCliArgs(args, opts = {}) {
|
|
|
22443
22655
|
i++;
|
|
22444
22656
|
}
|
|
22445
22657
|
}
|
|
22446
|
-
if (!simId) {
|
|
22658
|
+
if (!state.simId) {
|
|
22447
22659
|
const savedSim = readCurrentSim();
|
|
22448
22660
|
if (savedSim) {
|
|
22449
|
-
simId = savedSim.simId.trim() || void 0;
|
|
22450
|
-
simIdSource = "saved";
|
|
22661
|
+
state.simId = savedSim.simId.trim() || void 0;
|
|
22662
|
+
state.simIdSource = "saved";
|
|
22451
22663
|
}
|
|
22452
22664
|
}
|
|
22453
22665
|
return {
|
|
22454
22666
|
positional: args.filter((_, i) => !flagIndices.has(i)),
|
|
22455
|
-
wsPort,
|
|
22456
|
-
explicitPort,
|
|
22457
|
-
simId,
|
|
22458
|
-
simIdSource,
|
|
22459
|
-
commandTimeoutMs
|
|
22667
|
+
wsPort: state.wsPort,
|
|
22668
|
+
explicitPort: state.explicitPort,
|
|
22669
|
+
simId: state.simId,
|
|
22670
|
+
simIdSource: state.simIdSource,
|
|
22671
|
+
commandTimeoutMs: state.commandTimeoutMs
|
|
22460
22672
|
};
|
|
22461
22673
|
}
|
|
22462
22674
|
function createBridge(wsPort, opts = {}) {
|
|
@@ -22690,12 +22902,12 @@ async function callInBridge(bridge, path20, ...args) {
|
|
|
22690
22902
|
async function callInBridgeWrite(bridge, path20, ...args) {
|
|
22691
22903
|
return bridge.send({ type: "call", path: path20, args, acquireLock: true });
|
|
22692
22904
|
}
|
|
22693
|
-
var
|
|
22905
|
+
var import_node_fs15, import_node_path16, import_ws2, RNX_PLACEMENT_ENV, resolvedWorld, BridgeSimLockedError, BRIDGE_VALUE_FLAGS_TABLE, BRIDGE_VALUE_FLAGS;
|
|
22694
22906
|
var init_ws_bridge = __esm({
|
|
22695
22907
|
"cli/ws-bridge.ts"() {
|
|
22696
22908
|
"use strict";
|
|
22697
|
-
|
|
22698
|
-
|
|
22909
|
+
import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
22910
|
+
import_node_path16 = __toESM(require("node:path"), 1);
|
|
22699
22911
|
import_ws2 = require("ws");
|
|
22700
22912
|
init_bridge_constants();
|
|
22701
22913
|
init_cli_constants();
|
|
@@ -22712,6 +22924,39 @@ var init_ws_bridge = __esm({
|
|
|
22712
22924
|
this.lock = lock;
|
|
22713
22925
|
}
|
|
22714
22926
|
};
|
|
22927
|
+
BRIDGE_VALUE_FLAGS_TABLE = [
|
|
22928
|
+
{
|
|
22929
|
+
names: ["--port", "-p"],
|
|
22930
|
+
// naming the flag pins the world even when the value is missing or junk,
|
|
22931
|
+
// so a later --base-url cannot quietly retarget the run to another shell.
|
|
22932
|
+
apply: (state, value) => {
|
|
22933
|
+
state.explicitPort = true;
|
|
22934
|
+
if (value !== void 0) state.wsPort = Number(value);
|
|
22935
|
+
}
|
|
22936
|
+
},
|
|
22937
|
+
{
|
|
22938
|
+
names: ["--timeout"],
|
|
22939
|
+
apply: (state, value) => {
|
|
22940
|
+
if (value !== void 0) state.commandTimeoutMs = Number(value);
|
|
22941
|
+
}
|
|
22942
|
+
},
|
|
22943
|
+
{
|
|
22944
|
+
// `--sim` is the canonical target flag; `--session` / `--tab` are
|
|
22945
|
+
// documented aliases (CLAUDE.md, the rnx agent skills, and engine docs all
|
|
22946
|
+
// say `--session <id>`). without these aliases an agent following the docs
|
|
22947
|
+
// would have `--session ef` silently ignored and get the *currently
|
|
22948
|
+
// pinned* sim's tree instead — wrong-app data with no error.
|
|
22949
|
+
names: ["--sim", "--session", "--tab"],
|
|
22950
|
+
apply: (state, value) => {
|
|
22951
|
+
if (value === void 0) return;
|
|
22952
|
+
state.simId = value.trim() || void 0;
|
|
22953
|
+
state.simIdSource = "flag";
|
|
22954
|
+
}
|
|
22955
|
+
}
|
|
22956
|
+
];
|
|
22957
|
+
BRIDGE_VALUE_FLAGS = BRIDGE_VALUE_FLAGS_TABLE.flatMap(
|
|
22958
|
+
(flag) => [...flag.names]
|
|
22959
|
+
);
|
|
22715
22960
|
}
|
|
22716
22961
|
});
|
|
22717
22962
|
|
|
@@ -23060,9 +23305,9 @@ var init_profiles = __esm({
|
|
|
23060
23305
|
// cli/app-project.ts
|
|
23061
23306
|
function firstNamedFile(dir, names) {
|
|
23062
23307
|
for (const name2 of names) {
|
|
23063
|
-
const candidate =
|
|
23308
|
+
const candidate = import_node_path17.default.join(dir, name2);
|
|
23064
23309
|
try {
|
|
23065
|
-
if (
|
|
23310
|
+
if (import_node_fs16.default.statSync(candidate).isFile()) return candidate;
|
|
23066
23311
|
} catch {
|
|
23067
23312
|
}
|
|
23068
23313
|
}
|
|
@@ -23075,24 +23320,24 @@ function findRNXAppConfig(dir) {
|
|
|
23075
23320
|
return firstNamedFile(dir, RNX_APP_CONFIG_NAMES);
|
|
23076
23321
|
}
|
|
23077
23322
|
function resolveAppProject(projectRoot) {
|
|
23078
|
-
const appDir =
|
|
23323
|
+
const appDir = import_node_path17.default.resolve(projectRoot);
|
|
23079
23324
|
try {
|
|
23080
|
-
if (!
|
|
23325
|
+
if (!import_node_fs16.default.statSync(appDir).isDirectory()) return null;
|
|
23081
23326
|
} catch {
|
|
23082
23327
|
return null;
|
|
23083
23328
|
}
|
|
23084
23329
|
const configPath = findRNXAppConfig(appDir);
|
|
23085
|
-
if (!configPath && !findExpoAppConfig(appDir) && !
|
|
23330
|
+
if (!configPath && !findExpoAppConfig(appDir) && !import_node_fs16.default.existsSync(import_node_path17.default.join(appDir, "package.json"))) {
|
|
23086
23331
|
return null;
|
|
23087
23332
|
}
|
|
23088
23333
|
return { appDir, configPath };
|
|
23089
23334
|
}
|
|
23090
|
-
var
|
|
23335
|
+
var import_node_fs16, import_node_path17, EXPO_APP_CONFIG_NAMES, RNX_APP_CONFIG_NAMES;
|
|
23091
23336
|
var init_app_project = __esm({
|
|
23092
23337
|
"cli/app-project.ts"() {
|
|
23093
23338
|
"use strict";
|
|
23094
|
-
|
|
23095
|
-
|
|
23339
|
+
import_node_fs16 = __toESM(require("node:fs"), 1);
|
|
23340
|
+
import_node_path17 = __toESM(require("node:path"), 1);
|
|
23096
23341
|
EXPO_APP_CONFIG_NAMES = [
|
|
23097
23342
|
"app.config.js",
|
|
23098
23343
|
"app.config.ts",
|
|
@@ -23121,13 +23366,13 @@ function isRNXConfig(value) {
|
|
|
23121
23366
|
}
|
|
23122
23367
|
function resolveConfigReplacementFiles(config, configPath) {
|
|
23123
23368
|
if (!config.modules) return config;
|
|
23124
|
-
const configDir =
|
|
23369
|
+
const configDir = import_node_path18.default.dirname(configPath);
|
|
23125
23370
|
return {
|
|
23126
23371
|
...config,
|
|
23127
23372
|
modules: Object.fromEntries(
|
|
23128
23373
|
Object.entries(config.modules).map(([name2, resolution]) => [
|
|
23129
23374
|
name2,
|
|
23130
|
-
resolution && typeof resolution === "object" && "file" in resolution ? { ...resolution, file:
|
|
23375
|
+
resolution && typeof resolution === "object" && "file" in resolution ? { ...resolution, file: import_node_path18.default.resolve(configDir, resolution.file) } : resolution
|
|
23131
23376
|
])
|
|
23132
23377
|
)
|
|
23133
23378
|
};
|
|
@@ -23157,12 +23402,12 @@ async function resolveRNXAppConfig(startDir = process.cwd()) {
|
|
|
23157
23402
|
const project = resolveAppProject(startDir);
|
|
23158
23403
|
return { project, config: await loadRNXAppConfig(project) };
|
|
23159
23404
|
}
|
|
23160
|
-
var import_node_module,
|
|
23405
|
+
var import_node_module, import_node_path18, import_jiti, require2;
|
|
23161
23406
|
var init_app_config = __esm({
|
|
23162
23407
|
"cli/app-config.ts"() {
|
|
23163
23408
|
"use strict";
|
|
23164
23409
|
import_node_module = require("node:module");
|
|
23165
|
-
|
|
23410
|
+
import_node_path18 = __toESM(require("node:path"), 1);
|
|
23166
23411
|
init_src();
|
|
23167
23412
|
import_jiti = require("jiti");
|
|
23168
23413
|
init_public_brand();
|
|
@@ -23230,13 +23475,13 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
23230
23475
|
scannedFontDirectories++;
|
|
23231
23476
|
let entries;
|
|
23232
23477
|
try {
|
|
23233
|
-
entries =
|
|
23478
|
+
entries = import_node_fs17.default.readdirSync(current.dir, { withFileTypes: true });
|
|
23234
23479
|
} catch {
|
|
23235
23480
|
continue;
|
|
23236
23481
|
}
|
|
23237
23482
|
for (const entry of entries) {
|
|
23238
23483
|
if (entry.isSymbolicLink()) continue;
|
|
23239
|
-
const fullPath =
|
|
23484
|
+
const fullPath = import_node_path19.default.join(current.dir, entry.name);
|
|
23240
23485
|
if (entry.isDirectory()) {
|
|
23241
23486
|
if (current.depth < 4 && pending.length < 64 && !entry.name.startsWith(".")) {
|
|
23242
23487
|
pending.push({ dir: fullPath, depth: current.depth + 1 });
|
|
@@ -23244,15 +23489,15 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
23244
23489
|
continue;
|
|
23245
23490
|
}
|
|
23246
23491
|
if (!entry.isFile() || !/\.(ttf|otf|woff|woff2)$/i.test(entry.name)) continue;
|
|
23247
|
-
const relative =
|
|
23248
|
-
fontPaths.push(
|
|
23492
|
+
const relative = import_node_path19.default.relative(root, fullPath).split(import_node_path19.default.sep).join("/");
|
|
23493
|
+
fontPaths.push(import_node_path19.default.posix.join(metroPathPrefix, relative));
|
|
23249
23494
|
if (fontPaths.length >= 256) break;
|
|
23250
23495
|
}
|
|
23251
23496
|
}
|
|
23252
23497
|
};
|
|
23253
23498
|
try {
|
|
23254
23499
|
const packageJson = JSON.parse(
|
|
23255
|
-
|
|
23500
|
+
import_node_fs17.default.readFileSync(import_node_path19.default.join(selectedAppDir, "package.json"), "utf8")
|
|
23256
23501
|
);
|
|
23257
23502
|
const dependencyNames = /* @__PURE__ */ new Set();
|
|
23258
23503
|
for (const field of ["dependencies", "devDependencies", "optionalDependencies"]) {
|
|
@@ -23267,24 +23512,24 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
23267
23512
|
const config = Reflect.get(packageJson, "reactNativeVectorIcons");
|
|
23268
23513
|
const configuredFontDir = config && typeof config === "object" ? Reflect.get(config, "fontDir") : null;
|
|
23269
23514
|
const configuredDir = typeof configuredFontDir === "string" ? configuredFontDir : "rnvi-fonts";
|
|
23270
|
-
const root =
|
|
23271
|
-
const relativeRoot =
|
|
23272
|
-
if (!relativeRoot.startsWith("..") && !
|
|
23273
|
-
collectFontFiles(root, relativeRoot.split(
|
|
23515
|
+
const root = import_node_path19.default.resolve(selectedAppDir, configuredDir);
|
|
23516
|
+
const relativeRoot = import_node_path19.default.relative(selectedAppDir, root);
|
|
23517
|
+
if (!relativeRoot.startsWith("..") && !import_node_path19.default.isAbsolute(relativeRoot)) {
|
|
23518
|
+
collectFontFiles(root, relativeRoot.split(import_node_path19.default.sep).join("/"));
|
|
23274
23519
|
}
|
|
23275
|
-
const vectorIconRequire = (0, import_node_module2.createRequire)(
|
|
23520
|
+
const vectorIconRequire = (0, import_node_module2.createRequire)(import_node_path19.default.join(selectedAppDir, "package.json"));
|
|
23276
23521
|
for (const dependencyName of vectorIconDependencies) {
|
|
23277
23522
|
try {
|
|
23278
23523
|
const entryPath = vectorIconRequire.resolve(dependencyName);
|
|
23279
|
-
const dependencyPath = dependencyName.split("/").join(
|
|
23280
|
-
const marker = `${
|
|
23524
|
+
const dependencyPath = dependencyName.split("/").join(import_node_path19.default.sep);
|
|
23525
|
+
const marker = `${import_node_path19.default.sep}node_modules${import_node_path19.default.sep}${dependencyPath}${import_node_path19.default.sep}`;
|
|
23281
23526
|
const markerIndex = entryPath.lastIndexOf(marker);
|
|
23282
23527
|
if (markerIndex === -1) continue;
|
|
23283
23528
|
const packageRoot = entryPath.slice(0, markerIndex + marker.length - 1);
|
|
23284
23529
|
const fontsDir = dependencyName === "react-native-vector-icons" ? "Fonts" : "fonts";
|
|
23285
23530
|
collectFontFiles(
|
|
23286
|
-
|
|
23287
|
-
|
|
23531
|
+
import_node_path19.default.join(packageRoot, fontsDir),
|
|
23532
|
+
import_node_path19.default.posix.join("node_modules", dependencyName, fontsDir)
|
|
23288
23533
|
);
|
|
23289
23534
|
} catch {
|
|
23290
23535
|
}
|
|
@@ -23293,37 +23538,37 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
23293
23538
|
} catch {
|
|
23294
23539
|
}
|
|
23295
23540
|
try {
|
|
23296
|
-
const configPath =
|
|
23297
|
-
if (
|
|
23298
|
-
const appConfigRequire = (0, import_node_module2.createRequire)(
|
|
23541
|
+
const configPath = import_node_path19.default.join(selectedAppDir, "react-native.config.js");
|
|
23542
|
+
if (import_node_fs17.default.statSync(configPath).isFile()) {
|
|
23543
|
+
const appConfigRequire = (0, import_node_module2.createRequire)(import_node_path19.default.join(selectedAppDir, "package.json"));
|
|
23299
23544
|
const rnConfig = appConfigRequire(configPath);
|
|
23300
23545
|
const assets = rnConfig && typeof rnConfig === "object" ? Reflect.get(rnConfig, "assets") : null;
|
|
23301
23546
|
if (Array.isArray(assets)) {
|
|
23302
23547
|
for (const assetDir of assets) {
|
|
23303
23548
|
if (typeof assetDir !== "string") continue;
|
|
23304
|
-
const root =
|
|
23305
|
-
const relativeRoot =
|
|
23306
|
-
if (relativeRoot.startsWith("..") ||
|
|
23307
|
-
collectFontFiles(root, relativeRoot.split(
|
|
23549
|
+
const root = import_node_path19.default.resolve(selectedAppDir, assetDir);
|
|
23550
|
+
const relativeRoot = import_node_path19.default.relative(selectedAppDir, root);
|
|
23551
|
+
if (relativeRoot.startsWith("..") || import_node_path19.default.isAbsolute(relativeRoot)) continue;
|
|
23552
|
+
collectFontFiles(root, relativeRoot.split(import_node_path19.default.sep).join("/"));
|
|
23308
23553
|
}
|
|
23309
23554
|
}
|
|
23310
23555
|
}
|
|
23311
23556
|
} catch {
|
|
23312
23557
|
}
|
|
23313
23558
|
if (platform === "ios") {
|
|
23314
|
-
const iosDir =
|
|
23559
|
+
const iosDir = import_node_path19.default.join(selectedAppDir, "ios");
|
|
23315
23560
|
try {
|
|
23316
|
-
const targetDirs =
|
|
23561
|
+
const targetDirs = import_node_fs17.default.readdirSync(iosDir, { withFileTypes: true }).filter(
|
|
23317
23562
|
(entry) => entry.isDirectory() && !entry.isSymbolicLink() && entry.name !== "Pods" && entry.name !== "build" && !entry.name.startsWith(".")
|
|
23318
23563
|
).slice(0, 64);
|
|
23319
|
-
const plistPaths = [
|
|
23564
|
+
const plistPaths = [import_node_path19.default.join(iosDir, "Info.plist")];
|
|
23320
23565
|
for (const entry of targetDirs) {
|
|
23321
|
-
plistPaths.push(
|
|
23566
|
+
plistPaths.push(import_node_path19.default.join(iosDir, entry.name, "Info.plist"));
|
|
23322
23567
|
}
|
|
23323
23568
|
for (const plistPath of plistPaths) {
|
|
23324
23569
|
let parsed;
|
|
23325
23570
|
try {
|
|
23326
|
-
parsed = parsePlistSource(
|
|
23571
|
+
parsed = parsePlistSource(import_node_fs17.default.readFileSync(plistPath, "utf8"));
|
|
23327
23572
|
} catch {
|
|
23328
23573
|
continue;
|
|
23329
23574
|
}
|
|
@@ -23333,21 +23578,21 @@ function discoverNativeLinkedAppFonts(opts) {
|
|
|
23333
23578
|
for (const declaredFont of declaredFonts) {
|
|
23334
23579
|
if (typeof declaredFont !== "string") continue;
|
|
23335
23580
|
const candidates = [
|
|
23336
|
-
|
|
23337
|
-
|
|
23581
|
+
import_node_path19.default.resolve(import_node_path19.default.dirname(plistPath), declaredFont),
|
|
23582
|
+
import_node_path19.default.resolve(iosDir, declaredFont)
|
|
23338
23583
|
];
|
|
23339
23584
|
const fontPath = candidates.find((candidate) => {
|
|
23340
|
-
const relative =
|
|
23341
|
-
if (relative.startsWith("..") ||
|
|
23585
|
+
const relative = import_node_path19.default.relative(selectedAppDir, candidate);
|
|
23586
|
+
if (relative.startsWith("..") || import_node_path19.default.isAbsolute(relative)) return false;
|
|
23342
23587
|
try {
|
|
23343
|
-
return
|
|
23588
|
+
return import_node_fs17.default.statSync(candidate).isFile();
|
|
23344
23589
|
} catch {
|
|
23345
23590
|
return false;
|
|
23346
23591
|
}
|
|
23347
23592
|
});
|
|
23348
23593
|
if (!fontPath) continue;
|
|
23349
23594
|
fontPaths.push(
|
|
23350
|
-
|
|
23595
|
+
import_node_path19.default.relative(selectedAppDir, fontPath).split(import_node_path19.default.sep).join("/")
|
|
23351
23596
|
);
|
|
23352
23597
|
}
|
|
23353
23598
|
}
|
|
@@ -23386,13 +23631,13 @@ async function resolveMetroProjectRoot(bundleUrl, opts) {
|
|
|
23386
23631
|
function encodeAppFontsWire(specs) {
|
|
23387
23632
|
return specs.map((spec) => `${encodeURIComponent(spec.url)}::${encodeURIComponent(spec.family)}`).join(",");
|
|
23388
23633
|
}
|
|
23389
|
-
var
|
|
23634
|
+
var import_node_fs17, import_node_module2, import_node_path19, import_config_plugin_fonts, require3;
|
|
23390
23635
|
var init_app_fonts = __esm({
|
|
23391
23636
|
"cli/app-fonts.ts"() {
|
|
23392
23637
|
"use strict";
|
|
23393
|
-
|
|
23638
|
+
import_node_fs17 = __toESM(require("node:fs"), 1);
|
|
23394
23639
|
import_node_module2 = require("node:module");
|
|
23395
|
-
|
|
23640
|
+
import_node_path19 = __toESM(require("node:path"), 1);
|
|
23396
23641
|
import_config_plugin_fonts = require("sootsim-engine/engine/config-plugin-fonts");
|
|
23397
23642
|
init_dev_server_scanner();
|
|
23398
23643
|
init_plist();
|
|
@@ -24488,7 +24733,7 @@ function resolvePlaywright() {
|
|
|
24488
24733
|
try {
|
|
24489
24734
|
const modulePath = requireFromRoot.resolve(spec);
|
|
24490
24735
|
const packageJsonPath = requireFromRoot.resolve(`${spec}/package.json`);
|
|
24491
|
-
const parsed = JSON.parse((0,
|
|
24736
|
+
const parsed = JSON.parse((0, import_node_fs18.readFileSync)(packageJsonPath, "utf8"));
|
|
24492
24737
|
if (!isRecord5(parsed) || typeof parsed.version !== "string") continue;
|
|
24493
24738
|
const bin = parsed.bin;
|
|
24494
24739
|
let binPath = null;
|
|
@@ -24500,8 +24745,8 @@ function resolvePlaywright() {
|
|
|
24500
24745
|
binPath = typeof named === "string" ? named : typeof first === "string" ? first : null;
|
|
24501
24746
|
}
|
|
24502
24747
|
if (!binPath) continue;
|
|
24503
|
-
const cliPath = (0,
|
|
24504
|
-
if (!(0,
|
|
24748
|
+
const cliPath = (0, import_node_path20.join)((0, import_node_path20.dirname)(packageJsonPath), binPath);
|
|
24749
|
+
if (!(0, import_node_fs18.existsSync)(cliPath)) continue;
|
|
24505
24750
|
return {
|
|
24506
24751
|
spec,
|
|
24507
24752
|
modulePath,
|
|
@@ -24545,7 +24790,7 @@ function probeBrowser(resolved, env) {
|
|
|
24545
24790
|
return {
|
|
24546
24791
|
ok: true,
|
|
24547
24792
|
executablePath: parsed.executablePath,
|
|
24548
|
-
exists: parsed.exists && (0,
|
|
24793
|
+
exists: parsed.exists && (0, import_node_fs18.existsSync)(parsed.executablePath)
|
|
24549
24794
|
};
|
|
24550
24795
|
} catch (error) {
|
|
24551
24796
|
return {
|
|
@@ -24596,14 +24841,14 @@ ${detail}` : ""}`
|
|
|
24596
24841
|
}
|
|
24597
24842
|
return { ok: true, executablePath: after.executablePath, installed: true };
|
|
24598
24843
|
}
|
|
24599
|
-
var import_node_child_process6,
|
|
24844
|
+
var import_node_child_process6, import_node_fs18, import_node_module4, import_node_path20;
|
|
24600
24845
|
var init_playwright_provisioning = __esm({
|
|
24601
24846
|
"cli/drivers/playwright-provisioning.ts"() {
|
|
24602
24847
|
"use strict";
|
|
24603
24848
|
import_node_child_process6 = require("node:child_process");
|
|
24604
|
-
|
|
24849
|
+
import_node_fs18 = require("node:fs");
|
|
24605
24850
|
import_node_module4 = require("node:module");
|
|
24606
|
-
|
|
24851
|
+
import_node_path20 = require("node:path");
|
|
24607
24852
|
init_internal_child();
|
|
24608
24853
|
init_self_invocation();
|
|
24609
24854
|
}
|
|
@@ -24784,30 +25029,6 @@ var init_open_url2 = __esm({
|
|
|
24784
25029
|
}
|
|
24785
25030
|
});
|
|
24786
25031
|
|
|
24787
|
-
// cli/run-rnx.ts
|
|
24788
|
-
function rethrowIfExit(error) {
|
|
24789
|
-
if (error instanceof RnxExit) throw error;
|
|
24790
|
-
}
|
|
24791
|
-
function rnxExit(code) {
|
|
24792
|
-
throw new RnxExit(code);
|
|
24793
|
-
}
|
|
24794
|
-
var import_node_async_hooks, RnxExit, sinks;
|
|
24795
|
-
var init_run_rnx = __esm({
|
|
24796
|
-
"cli/run-rnx.ts"() {
|
|
24797
|
-
"use strict";
|
|
24798
|
-
import_node_async_hooks = require("node:async_hooks");
|
|
24799
|
-
RnxExit = class extends Error {
|
|
24800
|
-
code;
|
|
24801
|
-
constructor(code) {
|
|
24802
|
-
super(`rnx exited with code ${code}`);
|
|
24803
|
-
this.name = "RnxExit";
|
|
24804
|
-
this.code = code;
|
|
24805
|
-
}
|
|
24806
|
-
};
|
|
24807
|
-
sinks = new import_node_async_hooks.AsyncLocalStorage();
|
|
24808
|
-
}
|
|
24809
|
-
});
|
|
24810
|
-
|
|
24811
25032
|
// cli/commands/inspect/env.ts
|
|
24812
25033
|
function isAgentEnv(env = process.env) {
|
|
24813
25034
|
if (env.RNX_AGENT === "0") return false;
|
|
@@ -25289,7 +25510,7 @@ function assertExplicitBridgeLock(preferredPort, explicitPort, lock) {
|
|
|
25289
25510
|
}
|
|
25290
25511
|
async function ensureRuntimeForOpen() {
|
|
25291
25512
|
const active = readActiveRuntime();
|
|
25292
|
-
if (active &&
|
|
25513
|
+
if (active && import_node_fs19.default.existsSync(runtimeDir(active))) return;
|
|
25293
25514
|
console.error(" installing rnx engine runtime...");
|
|
25294
25515
|
const { runRuntime: runRuntime2 } = await Promise.resolve().then(() => (init_runtime(), runtime_exports));
|
|
25295
25516
|
await runRuntime2(["install"], {});
|
|
@@ -25436,10 +25657,10 @@ async function buildResolvedBundleOpenUrl(target, baseUrl, opts = {}) {
|
|
|
25436
25657
|
}
|
|
25437
25658
|
function normalizeReplacementPath(filePath) {
|
|
25438
25659
|
if (filePath.startsWith("~/")) {
|
|
25439
|
-
return
|
|
25660
|
+
return import_node_path21.default.join(import_node_os3.default.homedir(), filePath.slice(2));
|
|
25440
25661
|
}
|
|
25441
|
-
if (
|
|
25442
|
-
return
|
|
25662
|
+
if (import_node_path21.default.isAbsolute(filePath)) return filePath;
|
|
25663
|
+
return import_node_path21.default.resolve(process.cwd(), filePath);
|
|
25443
25664
|
}
|
|
25444
25665
|
function parseOpenRuntimeConfig(args) {
|
|
25445
25666
|
const modules = {};
|
|
@@ -25458,7 +25679,7 @@ function parseOpenRuntimeConfig(args) {
|
|
|
25458
25679
|
}
|
|
25459
25680
|
const moduleName = raw.slice(0, eqIndex).trim();
|
|
25460
25681
|
const filePath = normalizeReplacementPath(raw.slice(eqIndex + 1).trim());
|
|
25461
|
-
if (!
|
|
25682
|
+
if (!import_node_fs19.default.existsSync(filePath)) {
|
|
25462
25683
|
console.error(` rnx open: replacement file not found: ${filePath}`);
|
|
25463
25684
|
rnxExit(1);
|
|
25464
25685
|
}
|
|
@@ -25489,7 +25710,7 @@ async function resolveAppProjectForBundleUrl(bundleUrl) {
|
|
|
25489
25710
|
return advertisedRoot ? resolveAppProject(advertisedRoot) : null;
|
|
25490
25711
|
}
|
|
25491
25712
|
async function ensureConfiguredRuntime(version) {
|
|
25492
|
-
if (
|
|
25713
|
+
if (import_node_fs19.default.existsSync(import_node_path21.default.join(runtimeDir(version), "index.html"))) return;
|
|
25493
25714
|
console.error(` installing configured engine runtime ${version}...`);
|
|
25494
25715
|
const result = await rnxRuntime.install({
|
|
25495
25716
|
version,
|
|
@@ -25631,9 +25852,10 @@ async function buildShellUrl(target, baseUrl = resolveDefaultShellBaseUrl(), opt
|
|
|
25631
25852
|
const resolved = await resolveShellUrl(target, baseUrl, opts);
|
|
25632
25853
|
const project = opts.project ?? await resolveAppProjectForBundleUrl(bundleUrlOf(resolved));
|
|
25633
25854
|
const stamped = await stampAppSplash(await stampAppFonts(resolved, project), project);
|
|
25634
|
-
if (!opts.device) return stamped;
|
|
25855
|
+
if (!opts.device && !opts.proof) return stamped;
|
|
25635
25856
|
const url = new URL(stamped);
|
|
25636
|
-
url.searchParams.set("device", opts.device);
|
|
25857
|
+
if (opts.device) url.searchParams.set("device", opts.device);
|
|
25858
|
+
if (opts.proof) url.searchParams.set("proof", "1");
|
|
25637
25859
|
return url.toString();
|
|
25638
25860
|
}
|
|
25639
25861
|
function deriveCurrentSimBaseUrl(sim, fallback) {
|
|
@@ -25860,7 +26082,7 @@ function playwrightHostPidForSim(sim) {
|
|
|
25860
26082
|
function signalDriverLaunchConnected(result) {
|
|
25861
26083
|
if (!result.connectAckFile) return false;
|
|
25862
26084
|
try {
|
|
25863
|
-
|
|
26085
|
+
import_node_fs19.default.writeFileSync(
|
|
25864
26086
|
result.connectAckFile,
|
|
25865
26087
|
`${JSON.stringify({ connectedAt: Date.now(), pid: result.pid ?? null })}
|
|
25866
26088
|
`,
|
|
@@ -25874,19 +26096,19 @@ function signalDriverLaunchConnected(result) {
|
|
|
25874
26096
|
function printDriverDiagnosticLogTail(result) {
|
|
25875
26097
|
if (!result.diagnosticLogPath) return;
|
|
25876
26098
|
try {
|
|
25877
|
-
const detail =
|
|
26099
|
+
const detail = import_node_fs19.default.readFileSync(result.diagnosticLogPath, "utf8").trim();
|
|
25878
26100
|
if (!detail) {
|
|
25879
|
-
console.error(` ${
|
|
26101
|
+
console.error(` ${import_node_path21.default.basename(result.diagnosticLogPath)} was empty`);
|
|
25880
26102
|
return;
|
|
25881
26103
|
}
|
|
25882
26104
|
const shown = detail.length > 4e3 ? `\u2026
|
|
25883
26105
|
${detail.slice(-4e3)}` : detail;
|
|
25884
|
-
console.error(` ${
|
|
26106
|
+
console.error(` ${import_node_path21.default.basename(result.diagnosticLogPath)}:`);
|
|
25885
26107
|
console.error(shown);
|
|
25886
26108
|
} catch (err) {
|
|
25887
26109
|
const message = err instanceof Error ? err.message : String(err);
|
|
25888
26110
|
console.error(
|
|
25889
|
-
` failed to read ${
|
|
26111
|
+
` failed to read ${import_node_path21.default.basename(result.diagnosticLogPath)}: ${message}`
|
|
25890
26112
|
);
|
|
25891
26113
|
}
|
|
25892
26114
|
}
|
|
@@ -26120,7 +26342,8 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
26120
26342
|
"--hot",
|
|
26121
26343
|
"--no-hmr",
|
|
26122
26344
|
"--no-describe",
|
|
26123
|
-
"--quiet"
|
|
26345
|
+
"--quiet",
|
|
26346
|
+
"--proof"
|
|
26124
26347
|
],
|
|
26125
26348
|
stripValueFlags: [
|
|
26126
26349
|
"--base-url",
|
|
@@ -26208,9 +26431,18 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
26208
26431
|
await ensureConfiguredRuntime(configuredRuntimeVersion);
|
|
26209
26432
|
}
|
|
26210
26433
|
const explicitBaseUrl = args.find((_, i) => args[i - 1] === "--base-url");
|
|
26211
|
-
if (explicitBaseUrl
|
|
26212
|
-
const
|
|
26213
|
-
|
|
26434
|
+
if (explicitBaseUrl) {
|
|
26435
|
+
const pinned = resolveBridgePortForPin({
|
|
26436
|
+
baseUrl: explicitBaseUrl,
|
|
26437
|
+
wsPort: parsed.wsPort,
|
|
26438
|
+
explicitPort: parsed.explicitPort
|
|
26439
|
+
});
|
|
26440
|
+
if (pinned.error !== void 0) {
|
|
26441
|
+
console.error(` error: ${pinned.error}`);
|
|
26442
|
+
rnxExit(1);
|
|
26443
|
+
} else {
|
|
26444
|
+
parsed.wsPort = pinned.port;
|
|
26445
|
+
}
|
|
26214
26446
|
}
|
|
26215
26447
|
parsed.wsPort = await ensureBridgeForOpen(parsed.wsPort, parsed.explicitPort);
|
|
26216
26448
|
const requestedDriverId = args.find((_, i) => args[i - 1] === "--driver") || "";
|
|
@@ -26249,7 +26481,8 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
26249
26481
|
hot: hotMode,
|
|
26250
26482
|
device: deviceArg,
|
|
26251
26483
|
resolvedBundle,
|
|
26252
|
-
project
|
|
26484
|
+
project,
|
|
26485
|
+
proof: args.includes("--proof")
|
|
26253
26486
|
};
|
|
26254
26487
|
const selectedShellBaseUrl = configuredRuntimeVersion ? `http://localhost:${parsed.wsPort}/` : explicitBaseUrl || resolveShellBaseUrlForBridgePort(parsed.wsPort);
|
|
26255
26488
|
const baseUrl = applyRuntimeGenerationOrigin(
|
|
@@ -26384,9 +26617,12 @@ async function runOpenCommand(args, opts = {}) {
|
|
|
26384
26617
|
const result = await driver.launch({
|
|
26385
26618
|
url: openUrl2,
|
|
26386
26619
|
// the shell serves the sim page but its WS bridge may have drifted off
|
|
26387
|
-
// the shell-port-implied default. inject the
|
|
26388
|
-
// page does not reconnect to a stale world.
|
|
26389
|
-
|
|
26620
|
+
// the shell-port-implied default. inject the bridge this command settled
|
|
26621
|
+
// on so the page does not reconnect to a stale world. re-deriving it from
|
|
26622
|
+
// the shell URL could name a third port, since a bridge with no lockfile
|
|
26623
|
+
// resolves back to the default shell URL and that shell may belong to a
|
|
26624
|
+
// live world of its own.
|
|
26625
|
+
bridgePort: parsed.wsPort,
|
|
26390
26626
|
headless: driverHeadless,
|
|
26391
26627
|
profileId,
|
|
26392
26628
|
ephemeralProfile,
|
|
@@ -26726,14 +26962,14 @@ async function runCloseCommand(args, opts = {}) {
|
|
|
26726
26962
|
bridge.close();
|
|
26727
26963
|
}
|
|
26728
26964
|
}
|
|
26729
|
-
var import_node_child_process7,
|
|
26965
|
+
var import_node_child_process7, import_node_fs19, import_node_os3, import_node_path21, import_settings, import_ws4, DEFAULT_DRIVER_CONNECT_TIMEOUT_MS, DRIVER_CONNECT_INTERVAL_MS, DRIVER_CONNECT_HOST_GRACE_MS, OPEN_BRIDGE_SPAWN_TIMEOUT_MS, SHELL_APPS;
|
|
26730
26966
|
var init_control = __esm({
|
|
26731
26967
|
"cli/commands/control.ts"() {
|
|
26732
26968
|
"use strict";
|
|
26733
26969
|
import_node_child_process7 = require("node:child_process");
|
|
26734
|
-
|
|
26970
|
+
import_node_fs19 = __toESM(require("node:fs"), 1);
|
|
26735
26971
|
import_node_os3 = __toESM(require("node:os"), 1);
|
|
26736
|
-
|
|
26972
|
+
import_node_path21 = __toESM(require("node:path"), 1);
|
|
26737
26973
|
import_settings = require("sootsim-engine/settings");
|
|
26738
26974
|
import_ws4 = require("ws");
|
|
26739
26975
|
init_dev_server_scanner();
|
|
@@ -27583,157 +27819,6 @@ var init_maestro_js = __esm({
|
|
|
27583
27819
|
}
|
|
27584
27820
|
});
|
|
27585
27821
|
|
|
27586
|
-
// src/auth/shared-session.ts
|
|
27587
|
-
function getBaseDir() {
|
|
27588
|
-
const explicit = process.env[SESSION_FILE_ENV];
|
|
27589
|
-
if (explicit?.trim()) {
|
|
27590
|
-
return (0, import_node_path21.dirname)((0, import_node_path21.resolve)(explicit));
|
|
27591
|
-
}
|
|
27592
|
-
return electronUserDataDir();
|
|
27593
|
-
}
|
|
27594
|
-
function getSharedDesktopAuthFilePath() {
|
|
27595
|
-
const explicit = process.env[SESSION_FILE_ENV];
|
|
27596
|
-
if (explicit?.trim()) return (0, import_node_path21.resolve)(explicit);
|
|
27597
|
-
return (0, import_node_path21.join)(getBaseDir(), "desktop-auth.json");
|
|
27598
|
-
}
|
|
27599
|
-
function normalizeUser(input) {
|
|
27600
|
-
if (!input || typeof input !== "object") return null;
|
|
27601
|
-
const value = input;
|
|
27602
|
-
if (typeof value.id !== "string" || !value.id.trim()) return null;
|
|
27603
|
-
return {
|
|
27604
|
-
id: value.id.trim(),
|
|
27605
|
-
name: typeof value.name === "string" ? value.name : void 0,
|
|
27606
|
-
email: typeof value.email === "string" ? value.email : void 0,
|
|
27607
|
-
image: typeof value.image === "string" ? value.image : void 0,
|
|
27608
|
-
githubUsername: typeof value.githubUsername === "string" ? value.githubUsername : void 0,
|
|
27609
|
-
isAdmin: value.isAdmin === true,
|
|
27610
|
-
teams: Array.isArray(value.teams) ? value.teams.map((team) => {
|
|
27611
|
-
if (!team || typeof team !== "object") return null;
|
|
27612
|
-
const t = team;
|
|
27613
|
-
if (typeof t.id !== "string" || typeof t.name !== "string") return null;
|
|
27614
|
-
return {
|
|
27615
|
-
id: t.id,
|
|
27616
|
-
name: t.name,
|
|
27617
|
-
role: t.role === "owner" ? "owner" : "member",
|
|
27618
|
-
githubOrg: typeof t.githubOrg === "string" ? t.githubOrg : null
|
|
27619
|
-
};
|
|
27620
|
-
}).filter((team) => !!team) : void 0
|
|
27621
|
-
};
|
|
27622
|
-
}
|
|
27623
|
-
function normalizeSession(input) {
|
|
27624
|
-
if (!input || typeof input !== "object") return null;
|
|
27625
|
-
const value = input;
|
|
27626
|
-
if (value.version !== SESSION_VERSION) return null;
|
|
27627
|
-
if (typeof value.token !== "string" || !value.token.trim()) return null;
|
|
27628
|
-
const origin = typeof value.origin === "string" && value.origin.trim() ? value.origin.trim() : DEFAULT_ORIGIN;
|
|
27629
|
-
const source = value.source === "cli" || value.source === "electron" || value.source === "browser" || value.source === "unknown" ? value.source : "unknown";
|
|
27630
|
-
const updatedAt = typeof value.updatedAt === "string" && value.updatedAt ? value.updatedAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
27631
|
-
const validatedAt = typeof value.validatedAt === "string" && value.validatedAt ? value.validatedAt : void 0;
|
|
27632
|
-
return {
|
|
27633
|
-
version: SESSION_VERSION,
|
|
27634
|
-
token: value.token.trim(),
|
|
27635
|
-
user: normalizeUser(value.user),
|
|
27636
|
-
origin,
|
|
27637
|
-
source,
|
|
27638
|
-
updatedAt,
|
|
27639
|
-
validatedAt
|
|
27640
|
-
};
|
|
27641
|
-
}
|
|
27642
|
-
function readSharedDesktopAuthSession() {
|
|
27643
|
-
const filepath = getSharedDesktopAuthFilePath();
|
|
27644
|
-
if (!(0, import_node_fs19.existsSync)(filepath)) return null;
|
|
27645
|
-
try {
|
|
27646
|
-
const parsed = JSON.parse((0, import_node_fs19.readFileSync)(filepath, "utf8"));
|
|
27647
|
-
const normalized = normalizeSession(parsed);
|
|
27648
|
-
if (!normalized) {
|
|
27649
|
-
(0, import_node_fs19.rmSync)(filepath, { force: true });
|
|
27650
|
-
return null;
|
|
27651
|
-
}
|
|
27652
|
-
return normalized;
|
|
27653
|
-
} catch {
|
|
27654
|
-
(0, import_node_fs19.rmSync)(filepath, { force: true });
|
|
27655
|
-
return null;
|
|
27656
|
-
}
|
|
27657
|
-
}
|
|
27658
|
-
var import_node_fs19, import_node_path21, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
|
|
27659
|
-
var init_shared_session = __esm({
|
|
27660
|
-
"src/auth/shared-session.ts"() {
|
|
27661
|
-
"use strict";
|
|
27662
|
-
import_node_fs19 = require("node:fs");
|
|
27663
|
-
import_node_path21 = require("node:path");
|
|
27664
|
-
init_home_paths();
|
|
27665
|
-
SESSION_VERSION = 1;
|
|
27666
|
-
SESSION_FILE_ENV = "SOOTSIM_SHARED_AUTH_FILE";
|
|
27667
|
-
DEFAULT_ORIGIN = "https://contrast.dev";
|
|
27668
|
-
}
|
|
27669
|
-
});
|
|
27670
|
-
|
|
27671
|
-
// cli/auth.ts
|
|
27672
|
-
function looksLikeGitHubToken(token) {
|
|
27673
|
-
return Boolean(
|
|
27674
|
-
token && token.length >= 20 && GITHUB_TOKEN_PREFIXES.some((prefix) => token.startsWith(prefix))
|
|
27675
|
-
);
|
|
27676
|
-
}
|
|
27677
|
-
function resolveGitHubActionsAuth() {
|
|
27678
|
-
const contrastRunnerToken = process.env.CONTRAST_INSTALLATION_TOKEN?.trim();
|
|
27679
|
-
const githubActionsToken = process.env.GITHUB_TOKEN?.trim();
|
|
27680
|
-
const token = contrastRunnerToken || githubActionsToken;
|
|
27681
|
-
if (!looksLikeGitHubToken(token)) return null;
|
|
27682
|
-
const repoSlug = (process.env.CONTRAST_REPO || process.env.GITHUB_REPOSITORY || "").trim();
|
|
27683
|
-
if (!repoSlug) return null;
|
|
27684
|
-
const [owner, repo] = repoSlug.includes("/") ? repoSlug.split("/", 2) : [null, null];
|
|
27685
|
-
const repositoryId = (process.env.CONTRAST_REPO_ID || process.env.GITHUB_REPOSITORY_ID || "").trim();
|
|
27686
|
-
const installationId = (process.env.CONTRAST_INSTALLATION_ID || process.env.GITHUB_APP_INSTALLATION_ID || "").trim();
|
|
27687
|
-
return {
|
|
27688
|
-
kind: "github",
|
|
27689
|
-
token,
|
|
27690
|
-
repoId: repoSlug,
|
|
27691
|
-
repositoryId: repositoryId || null,
|
|
27692
|
-
owner: owner || null,
|
|
27693
|
-
repo: repo || null,
|
|
27694
|
-
installationId: installationId || null,
|
|
27695
|
-
source: contrastRunnerToken ? "contrast-runner" : "github-actions"
|
|
27696
|
-
};
|
|
27697
|
-
}
|
|
27698
|
-
function isCliApiKeySecret(secret) {
|
|
27699
|
-
return secret.startsWith("sk_rnx_");
|
|
27700
|
-
}
|
|
27701
|
-
function readApiKeyFromEnv() {
|
|
27702
|
-
const envName = "RNX_API_KEY";
|
|
27703
|
-
const secret = process.env[envName]?.trim();
|
|
27704
|
-
return secret && isCliApiKeySecret(secret) ? { secret, envName } : null;
|
|
27705
|
-
}
|
|
27706
|
-
function resolveCliAuth() {
|
|
27707
|
-
const envKey = readApiKeyFromEnv();
|
|
27708
|
-
if (envKey) {
|
|
27709
|
-
return {
|
|
27710
|
-
kind: "api-key",
|
|
27711
|
-
secret: envKey.secret,
|
|
27712
|
-
source: "env",
|
|
27713
|
-
envName: envKey.envName
|
|
27714
|
-
};
|
|
27715
|
-
}
|
|
27716
|
-
const githubAuth = resolveGitHubActionsAuth();
|
|
27717
|
-
if (githubAuth) return githubAuth;
|
|
27718
|
-
const session = readSharedDesktopAuthSession();
|
|
27719
|
-
if (session?.token) {
|
|
27720
|
-
return { kind: "session", token: session.token, origin: session.origin };
|
|
27721
|
-
}
|
|
27722
|
-
return null;
|
|
27723
|
-
}
|
|
27724
|
-
function authHeaderValue(auth) {
|
|
27725
|
-
return auth.kind === "api-key" ? `Bearer ${auth.secret}` : `Bearer ${auth.token}`;
|
|
27726
|
-
}
|
|
27727
|
-
var GITHUB_TOKEN_PREFIXES;
|
|
27728
|
-
var init_auth = __esm({
|
|
27729
|
-
"cli/auth.ts"() {
|
|
27730
|
-
"use strict";
|
|
27731
|
-
init_shared_session();
|
|
27732
|
-
init_run_rnx();
|
|
27733
|
-
GITHUB_TOKEN_PREFIXES = ["ghs_", "ghp_", "gho_", "ghu_", "github_pat_"];
|
|
27734
|
-
}
|
|
27735
|
-
});
|
|
27736
|
-
|
|
27737
27822
|
// cli/run-registry.ts
|
|
27738
27823
|
var init_run_registry = __esm({
|
|
27739
27824
|
"cli/run-registry.ts"() {
|