rnxsim 0.1.513 → 0.1.515

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.
Files changed (60) hide show
  1. package/cli/cloud-client.ts +18 -8
  2. package/cli/commands/inspect/get-layout.ts +2 -1
  3. package/cli/outbound-endpoints.ts +1 -7
  4. package/dist-lib/agent-daemon-client.cjs +1 -1
  5. package/dist-lib/agent-events.cjs +1 -1
  6. package/dist-lib/agent-identity.cjs +1 -1
  7. package/dist-lib/agent-sessions.cjs +1 -1
  8. package/dist-lib/attached-projects.cjs +1 -1
  9. package/dist-lib/auth/shared-session.cjs +1 -1
  10. package/dist-lib/backend-origin.cjs +1 -1
  11. package/dist-lib/beta.cjs +1 -1
  12. package/dist-lib/beta.mjs +1 -1
  13. package/dist-lib/bridge-constants.cjs +1 -1
  14. package/dist-lib/bridge-contract-input.cjs +64 -1
  15. package/dist-lib/bridge-contract-input.mjs +63 -1
  16. package/dist-lib/bridge-contract.cjs +73 -3
  17. package/dist-lib/bridge-contract.mjs +69 -2
  18. package/dist-lib/capture-contract.cjs +1 -1
  19. package/dist-lib/capture-contract.mjs +1 -1
  20. package/dist-lib/cli-constants.cjs +1 -1
  21. package/dist-lib/cloud-contract.cjs +117 -22
  22. package/dist-lib/cloud-contract.mjs +104 -21
  23. package/dist-lib/cloud.cjs +121 -27
  24. package/dist-lib/cloud.mjs +121 -27
  25. package/dist-lib/config.cjs +1 -1
  26. package/dist-lib/detox/index.cjs +1 -1
  27. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  28. package/dist-lib/home-paths.cjs +1 -1
  29. package/dist-lib/host/bridge-host.cjs +45 -20
  30. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  31. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  32. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  33. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  34. package/dist-lib/host/websocket-proxy.cjs +1 -1
  35. package/dist-lib/index.cjs +62 -24
  36. package/dist-lib/jump-to-source-babel.cjs +1 -1
  37. package/dist-lib/jump-to-source-native.cjs +1 -1
  38. package/dist-lib/menu.cjs +1 -1
  39. package/dist-lib/menu.mjs +1 -1
  40. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  41. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  42. package/dist-lib/metro-production-bundle.cjs +1 -1
  43. package/dist-lib/metro-production-bundle.mjs +1 -1
  44. package/dist-lib/metro.cjs +1 -1
  45. package/dist-lib/profiles.cjs +1 -1
  46. package/dist-lib/public-brand.cjs +1 -1
  47. package/dist-lib/react-native-host-modules.cjs +1 -1
  48. package/dist-lib/react-native-host-modules.mjs +1 -1
  49. package/dist-lib/render-mode.cjs +1 -1
  50. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  51. package/dist-lib/sdk.cjs +1 -1
  52. package/dist-lib/sdk.mjs +1 -1
  53. package/dist-lib/skills.cjs +62 -24
  54. package/dist-lib/swift.cjs +1 -1
  55. package/dist-lib/vite.cjs +1 -1
  56. package/package.json +2 -1
  57. package/src/bridge-contract-input.ts +74 -0
  58. package/src/bridge-contract.ts +103 -0
  59. package/src/cloud-contract.ts +191 -19
  60. package/src/cloud.ts +104 -7
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -72,29 +72,60 @@ function isRnxScreenCapture(value) {
72
72
  // src/cloud-contract.ts
73
73
  var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
74
74
  var RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
75
- var RNX_CLOUD_COMMAND_TYPES = Object.freeze([
76
- "state",
77
- "query",
78
- "resolve",
79
- "perform",
80
- "waitFor",
81
- "reset",
82
- "screenshot",
83
- "capture",
84
- "captureRegions",
85
- "settle",
86
- "setAppearance",
87
- "openUrl",
88
- "tree",
89
- "tap",
90
- "longPress",
91
- "memory",
92
- "diagnostics"
93
- ]);
75
+ var RNX_CLOUD_COMMAND_SCOPES = {
76
+ state: "read",
77
+ tree: "read",
78
+ query: "read",
79
+ resolve: "read",
80
+ screenshot: "read",
81
+ capture: "read",
82
+ captureRegions: "read",
83
+ memory: "read",
84
+ diagnostics: "read",
85
+ storageSnapshot: "read",
86
+ perform: "drive",
87
+ waitFor: "drive",
88
+ tap: "drive",
89
+ longPress: "drive",
90
+ settle: "drive",
91
+ openUrl: "drive",
92
+ setAppearance: "drive",
93
+ keyboard: "drive",
94
+ focus: "drive",
95
+ flowStatus: "drive",
96
+ reset: "reset",
97
+ camera: "media",
98
+ // string evaluation and arbitrary bridge calls are maestro's boundary: the
99
+ // customer sdk never carries this scope, and the service grants it only to
100
+ // the account api key caller. close rides along, since ending the page ends
101
+ // the sim and belongs to the sim's owner rather than any driver.
102
+ evaluate: "debug",
103
+ call: "debug",
104
+ close: "debug"
105
+ };
106
+ function scopeTableKeys() {
107
+ return Object.keys(RNX_CLOUD_COMMAND_SCOPES).filter(
108
+ (key) => Object.prototype.hasOwnProperty.call(RNX_CLOUD_COMMAND_SCOPES, key)
109
+ );
110
+ }
111
+ var RNX_CLOUD_COMMAND_TYPES = Object.freeze(scopeTableKeys());
94
112
  var RNX_CLOUD_COMMAND_TYPE_SET = new Set(RNX_CLOUD_COMMAND_TYPES);
95
113
  function isRnxCloudCommandType(value) {
96
114
  return RNX_CLOUD_COMMAND_TYPE_SET.has(value);
97
115
  }
116
+ function rnxCloudCommandScope(type) {
117
+ return RNX_CLOUD_COMMAND_SCOPES[type];
118
+ }
119
+ var RNX_CLOUD_TOKEN_SCOPES = Object.freeze([
120
+ "read",
121
+ "drive",
122
+ "reset",
123
+ "media"
124
+ ]);
125
+ var RNX_CLOUD_ALL_COMMAND_SCOPES = Object.freeze(["read", "drive", "reset", "media", "debug"]);
126
+ function rnxCloudScopesAllowCommand(scopes, type) {
127
+ return scopes.includes(RNX_CLOUD_COMMAND_SCOPES[type]);
128
+ }
98
129
 
99
130
  // src/public-brand.ts
100
131
  var name = "rnx";
@@ -109,6 +140,8 @@ var rnxPublicBrand = Object.freeze({
109
140
  // src/cloud.ts
110
141
  var DEFAULT_DEVICE = "iphone-16";
111
142
  var DEFAULT_WAIT_READY_MS = 2e4;
143
+ var CLOUD_MAX_RETRIES = 2;
144
+ var CLOUD_NEVER_RETRY_CODES = /* @__PURE__ */ new Set(["concurrency_limit", "early_access"]);
112
145
  function isRecord(value) {
113
146
  return value !== null && typeof value === "object" && !Array.isArray(value);
114
147
  }
@@ -146,6 +179,62 @@ function responseError(status, text) {
146
179
  `RNX Cloud request failed (${status})${text.trim() ? `: ${text.trim()}` : ""}`
147
180
  );
148
181
  }
182
+ function readCloudErrorCode(text) {
183
+ let parsed;
184
+ try {
185
+ parsed = JSON.parse(text);
186
+ } catch {
187
+ return null;
188
+ }
189
+ if (!isRecord(parsed)) return null;
190
+ if (typeof parsed.error === "string") return parsed.error;
191
+ if (isRecord(parsed.error) && typeof parsed.error.code === "string") {
192
+ return parsed.error.code;
193
+ }
194
+ return null;
195
+ }
196
+ function readRetryAfterMs(response, text) {
197
+ const header = response.headers.get("retry-after");
198
+ if (header !== null) {
199
+ const seconds = Number(header.trim());
200
+ if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
201
+ }
202
+ let parsed;
203
+ try {
204
+ parsed = JSON.parse(text);
205
+ } catch {
206
+ return null;
207
+ }
208
+ if (isRecord(parsed) && typeof parsed.retryAfterMs === "number" && Number.isFinite(parsed.retryAfterMs) && parsed.retryAfterMs >= 0) {
209
+ return parsed.retryAfterMs;
210
+ }
211
+ return null;
212
+ }
213
+ function sleep(ms) {
214
+ return new Promise((resolve) => setTimeout(resolve, ms));
215
+ }
216
+ async function fetchWithCloudRetry(url, init, options) {
217
+ let attempt = 0;
218
+ for (; ; ) {
219
+ const response = await fetch(
220
+ url,
221
+ options?.timeoutMs === void 0 ? init : { ...init, signal: AbortSignal.timeout(options.timeoutMs) }
222
+ );
223
+ if (response.ok) return response;
224
+ const retryableStatus = response.status === 429 || response.status >= 500;
225
+ if (!retryableStatus || attempt >= CLOUD_MAX_RETRIES) return response;
226
+ const text = await response.text();
227
+ const code = readCloudErrorCode(text);
228
+ const retryable = response.status >= 500 ? !(code !== null && CLOUD_NEVER_RETRY_CODES.has(code)) : code === "rate_limited";
229
+ if (!retryable) {
230
+ return new Response(text, { status: response.status, headers: response.headers });
231
+ }
232
+ if (response.status === 429) {
233
+ await sleep(readRetryAfterMs(response, text) ?? 1e3);
234
+ }
235
+ attempt += 1;
236
+ }
237
+ }
149
238
  function copyArrayBuffer(bytes) {
150
239
  const copy = new ArrayBuffer(bytes.byteLength);
151
240
  new Uint8Array(copy).set(bytes);
@@ -228,6 +317,11 @@ function cloudCommand(command) {
228
317
  if (!isRnxCloudCommandType(command.type)) {
229
318
  throw new Error(`RNX Cloud does not support bridge command type ${command.type}`);
230
319
  }
320
+ if (!rnxCloudScopesAllowCommand(RNX_CLOUD_TOKEN_SCOPES, command.type)) {
321
+ throw new Error(
322
+ `RNX Cloud command ${command.type} requires the ${rnxCloudCommandScope(command.type)} scope`
323
+ );
324
+ }
231
325
  return { ...clean, type: command.type };
232
326
  }
233
327
  var RemoteSimulator = class {
@@ -294,7 +388,7 @@ var RemoteSimulator = class {
294
388
  };
295
389
  let response;
296
390
  try {
297
- response = await fetch(
391
+ response = await fetchWithCloudRetry(
298
392
  `${this.session.origin}/v1/sims/${encodeURIComponent(this.session.simId)}/commands`,
299
393
  {
300
394
  method: "POST",
@@ -302,9 +396,9 @@ var RemoteSimulator = class {
302
396
  authorization: `Bearer ${this.session.simulatorToken}`,
303
397
  "content-type": "application/json"
304
398
  },
305
- body: JSON.stringify(body),
306
- ...options?.timeoutMs ? { signal: AbortSignal.timeout(options.timeoutMs) } : {}
307
- }
399
+ body: JSON.stringify(body)
400
+ },
401
+ options?.timeoutMs === void 0 ? void 0 : { timeoutMs: options.timeoutMs }
308
402
  );
309
403
  } catch (error) {
310
404
  throw new Error(
@@ -329,7 +423,7 @@ var RemoteSimulator = class {
329
423
  return parsed.result;
330
424
  }
331
425
  async confirm() {
332
- const response = await fetch(
426
+ const response = await fetchWithCloudRetry(
333
427
  `${this.session.origin}/v1/sims/${encodeURIComponent(this.session.simId)}/claim`,
334
428
  {
335
429
  method: "POST",
@@ -356,7 +450,7 @@ var RemoteSimulator = class {
356
450
  return claim;
357
451
  }
358
452
  async close() {
359
- const response = await fetch(
453
+ const response = await fetchWithCloudRetry(
360
454
  `${this.session.origin}/v1/boxes/${encodeURIComponent(this.session.boxId)}`,
361
455
  {
362
456
  method: "DELETE",
@@ -387,7 +481,7 @@ async function createRemoteSimulator(input) {
387
481
  const device = input.device?.trim() || DEFAULT_DEVICE;
388
482
  let response;
389
483
  try {
390
- response = await fetch(`${origin}/v1/boxes`, {
484
+ response = await fetchWithCloudRetry(`${origin}/v1/boxes`, {
391
485
  method: "POST",
392
486
  headers: {
393
487
  authorization: input.authorization,
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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;
@@ -3488,32 +3488,57 @@ var init_metro_fingerprint = __esm({
3488
3488
  });
3489
3489
 
3490
3490
  // src/cloud-contract.ts
3491
- var RNX_CLOUD_MAX_ARTIFACT_BYTES, RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES, RNX_CLOUD_COMMAND_TYPES, RNX_CLOUD_COMMAND_TYPE_SET;
3491
+ function scopeTableKeys() {
3492
+ return Object.keys(RNX_CLOUD_COMMAND_SCOPES).filter(
3493
+ (key) => Object.prototype.hasOwnProperty.call(RNX_CLOUD_COMMAND_SCOPES, key)
3494
+ );
3495
+ }
3496
+ var RNX_CLOUD_MAX_ARTIFACT_BYTES, RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES, RNX_CLOUD_COMMAND_SCOPES, RNX_CLOUD_COMMAND_TYPES, RNX_CLOUD_COMMAND_TYPE_SET, RNX_CLOUD_TOKEN_SCOPES, RNX_CLOUD_ALL_COMMAND_SCOPES;
3492
3497
  var init_cloud_contract = __esm({
3493
3498
  "src/cloud-contract.ts"() {
3494
3499
  "use strict";
3495
3500
  RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
3496
3501
  RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
3497
- RNX_CLOUD_COMMAND_TYPES = Object.freeze([
3498
- "state",
3499
- "query",
3500
- "resolve",
3501
- "perform",
3502
- "waitFor",
3502
+ RNX_CLOUD_COMMAND_SCOPES = {
3503
+ state: "read",
3504
+ tree: "read",
3505
+ query: "read",
3506
+ resolve: "read",
3507
+ screenshot: "read",
3508
+ capture: "read",
3509
+ captureRegions: "read",
3510
+ memory: "read",
3511
+ diagnostics: "read",
3512
+ storageSnapshot: "read",
3513
+ perform: "drive",
3514
+ waitFor: "drive",
3515
+ tap: "drive",
3516
+ longPress: "drive",
3517
+ settle: "drive",
3518
+ openUrl: "drive",
3519
+ setAppearance: "drive",
3520
+ keyboard: "drive",
3521
+ focus: "drive",
3522
+ flowStatus: "drive",
3523
+ reset: "reset",
3524
+ camera: "media",
3525
+ // string evaluation and arbitrary bridge calls are maestro's boundary: the
3526
+ // customer sdk never carries this scope, and the service grants it only to
3527
+ // the account api key caller. close rides along, since ending the page ends
3528
+ // the sim and belongs to the sim's owner rather than any driver.
3529
+ evaluate: "debug",
3530
+ call: "debug",
3531
+ close: "debug"
3532
+ };
3533
+ RNX_CLOUD_COMMAND_TYPES = Object.freeze(scopeTableKeys());
3534
+ RNX_CLOUD_COMMAND_TYPE_SET = new Set(RNX_CLOUD_COMMAND_TYPES);
3535
+ RNX_CLOUD_TOKEN_SCOPES = Object.freeze([
3536
+ "read",
3537
+ "drive",
3503
3538
  "reset",
3504
- "screenshot",
3505
- "capture",
3506
- "captureRegions",
3507
- "settle",
3508
- "setAppearance",
3509
- "openUrl",
3510
- "tree",
3511
- "tap",
3512
- "longPress",
3513
- "memory",
3514
- "diagnostics"
3539
+ "media"
3515
3540
  ]);
3516
- RNX_CLOUD_COMMAND_TYPE_SET = new Set(RNX_CLOUD_COMMAND_TYPES);
3541
+ RNX_CLOUD_ALL_COMMAND_SCOPES = Object.freeze(["read", "drive", "reset", "media", "debug"]);
3517
3542
  }
3518
3543
  });
3519
3544
 
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/host/fetch-proxy-overrides.ts
4
4
  var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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;
@@ -78,29 +78,60 @@ function isLoopbackHost(hostname) {
78
78
  // src/cloud-contract.ts
79
79
  var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
80
80
  var RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
81
- var RNX_CLOUD_COMMAND_TYPES = Object.freeze([
82
- "state",
83
- "query",
84
- "resolve",
85
- "perform",
86
- "waitFor",
87
- "reset",
88
- "screenshot",
89
- "capture",
90
- "captureRegions",
91
- "settle",
92
- "setAppearance",
93
- "openUrl",
94
- "tree",
95
- "tap",
96
- "longPress",
97
- "memory",
98
- "diagnostics"
99
- ]);
81
+ var RNX_CLOUD_COMMAND_SCOPES = {
82
+ state: "read",
83
+ tree: "read",
84
+ query: "read",
85
+ resolve: "read",
86
+ screenshot: "read",
87
+ capture: "read",
88
+ captureRegions: "read",
89
+ memory: "read",
90
+ diagnostics: "read",
91
+ storageSnapshot: "read",
92
+ perform: "drive",
93
+ waitFor: "drive",
94
+ tap: "drive",
95
+ longPress: "drive",
96
+ settle: "drive",
97
+ openUrl: "drive",
98
+ setAppearance: "drive",
99
+ keyboard: "drive",
100
+ focus: "drive",
101
+ flowStatus: "drive",
102
+ reset: "reset",
103
+ camera: "media",
104
+ // string evaluation and arbitrary bridge calls are maestro's boundary: the
105
+ // customer sdk never carries this scope, and the service grants it only to
106
+ // the account api key caller. close rides along, since ending the page ends
107
+ // the sim and belongs to the sim's owner rather than any driver.
108
+ evaluate: "debug",
109
+ call: "debug",
110
+ close: "debug"
111
+ };
112
+ function scopeTableKeys() {
113
+ return Object.keys(RNX_CLOUD_COMMAND_SCOPES).filter(
114
+ (key) => Object.prototype.hasOwnProperty.call(RNX_CLOUD_COMMAND_SCOPES, key)
115
+ );
116
+ }
117
+ var RNX_CLOUD_COMMAND_TYPES = Object.freeze(scopeTableKeys());
100
118
  var RNX_CLOUD_COMMAND_TYPE_SET = new Set(RNX_CLOUD_COMMAND_TYPES);
101
119
  function isRnxCloudCommandType(value) {
102
120
  return RNX_CLOUD_COMMAND_TYPE_SET.has(value);
103
121
  }
122
+ function rnxCloudCommandScope(type) {
123
+ return RNX_CLOUD_COMMAND_SCOPES[type];
124
+ }
125
+ var RNX_CLOUD_TOKEN_SCOPES = Object.freeze([
126
+ "read",
127
+ "drive",
128
+ "reset",
129
+ "media"
130
+ ]);
131
+ var RNX_CLOUD_ALL_COMMAND_SCOPES = Object.freeze(["read", "drive", "reset", "media", "debug"]);
132
+ function rnxCloudScopesAllowCommand(scopes, type) {
133
+ return scopes.includes(RNX_CLOUD_COMMAND_SCOPES[type]);
134
+ }
104
135
 
105
136
  // src/metro-production-bundle.ts
106
137
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
@@ -444,10 +475,17 @@ function cloudCommand(command) {
444
475
  for (const [key, value] of Object.entries(command)) {
445
476
  if (key !== "id" && key !== "simId") clean[key] = value;
446
477
  }
447
- if (isRnxCloudCommandType(command.type)) return clean;
448
- throw new Error(
449
- `a remote simulator does not support bridge command type ${command.type}`
450
- );
478
+ if (!isRnxCloudCommandType(command.type)) {
479
+ throw new Error(
480
+ `a remote simulator does not support bridge command type ${command.type}`
481
+ );
482
+ }
483
+ if (!rnxCloudScopesAllowCommand(RNX_CLOUD_TOKEN_SCOPES, command.type)) {
484
+ throw new Error(
485
+ `a remote simulator command ${command.type} requires the ${rnxCloudCommandScope(command.type)} scope`
486
+ );
487
+ }
488
+ return clean;
451
489
  }
452
490
  var CloudBridge = class {
453
491
  constructor(session) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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;
package/dist-lib/menu.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/public-brand.ts
4
4
  var name = "rnx";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/metro-fingerprint-registry.ts
4
4
  var RNX_METRO_FINGERPRINT_SCHEMA_VERSION = 2;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/metro-production-bundle.ts
4
4
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/react-native-host-modules.ts
4
4
  var REACT_NATIVE_PASSTHROUGH_SPECIFIERS = [
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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;
package/dist-lib/sdk.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (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/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.513 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.515 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);