rnxsim 0.1.516 → 0.1.517

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 (55) hide show
  1. package/dist-lib/agent-daemon-client.cjs +1 -1
  2. package/dist-lib/agent-events.cjs +1 -1
  3. package/dist-lib/agent-identity.cjs +1 -1
  4. package/dist-lib/agent-sessions.cjs +1 -1
  5. package/dist-lib/attached-projects.cjs +1 -1
  6. package/dist-lib/auth/shared-session.cjs +1 -1
  7. package/dist-lib/backend-origin.cjs +1 -1
  8. package/dist-lib/beta.cjs +1 -1
  9. package/dist-lib/beta.mjs +1 -1
  10. package/dist-lib/bridge-constants.cjs +1 -1
  11. package/dist-lib/bridge-contract-input.cjs +1 -1
  12. package/dist-lib/bridge-contract-input.mjs +1 -1
  13. package/dist-lib/bridge-contract.cjs +1 -1
  14. package/dist-lib/bridge-contract.mjs +1 -1
  15. package/dist-lib/capture-contract.cjs +1 -1
  16. package/dist-lib/capture-contract.mjs +1 -1
  17. package/dist-lib/cli-constants.cjs +1 -1
  18. package/dist-lib/cloud-contract.cjs +29 -1
  19. package/dist-lib/cloud-contract.mjs +23 -1
  20. package/dist-lib/cloud.cjs +114 -16
  21. package/dist-lib/cloud.mjs +111 -16
  22. package/dist-lib/config.cjs +1 -1
  23. package/dist-lib/detox/index.cjs +1 -1
  24. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  25. package/dist-lib/home-paths.cjs +1 -1
  26. package/dist-lib/host/bridge-host.cjs +1 -1
  27. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  28. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  29. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  30. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  31. package/dist-lib/host/websocket-proxy.cjs +1 -1
  32. package/dist-lib/index.cjs +1 -1
  33. package/dist-lib/jump-to-source-babel.cjs +1 -1
  34. package/dist-lib/jump-to-source-native.cjs +1 -1
  35. package/dist-lib/menu.cjs +1 -1
  36. package/dist-lib/menu.mjs +1 -1
  37. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  38. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  39. package/dist-lib/metro-production-bundle.cjs +1 -1
  40. package/dist-lib/metro-production-bundle.mjs +1 -1
  41. package/dist-lib/metro.cjs +1 -1
  42. package/dist-lib/profiles.cjs +1 -1
  43. package/dist-lib/public-brand.cjs +1 -1
  44. package/dist-lib/react-native-host-modules.cjs +1 -1
  45. package/dist-lib/react-native-host-modules.mjs +1 -1
  46. package/dist-lib/render-mode.cjs +1 -1
  47. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  48. package/dist-lib/sdk.cjs +1 -1
  49. package/dist-lib/sdk.mjs +1 -1
  50. package/dist-lib/skills.cjs +1 -1
  51. package/dist-lib/swift.cjs +1 -1
  52. package/dist-lib/vite.cjs +1 -1
  53. package/package.json +1 -1
  54. package/src/cloud-contract.ts +37 -1
  55. package/src/cloud.ts +178 -21
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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/beta.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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/beta.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/beta.ts
4
4
  var IS_BETA = true;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var SIM_LONG_PRESS_MAX_MS = 5e3;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var REFUSED_PERFORM_STEP_TYPES = [
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/capture-contract.ts
4
4
  var RNX_SCREEN_CAPTURE_VERSION = 1;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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;
@@ -30,9 +30,15 @@ __export(cloud_contract_exports, {
30
30
  RNX_CLOUD_LABELS_MAX_COUNT: () => RNX_CLOUD_LABELS_MAX_COUNT,
31
31
  RNX_CLOUD_LABEL_MAX_LENGTH: () => RNX_CLOUD_LABEL_MAX_LENGTH,
32
32
  RNX_CLOUD_MAX_ARTIFACT_BYTES: () => RNX_CLOUD_MAX_ARTIFACT_BYTES,
33
+ RNX_CLOUD_SCOPED_TOKEN_DEFAULT_TTL_SECONDS: () => RNX_CLOUD_SCOPED_TOKEN_DEFAULT_TTL_SECONDS,
34
+ RNX_CLOUD_SCOPED_TOKEN_MAX_ORIGINS: () => RNX_CLOUD_SCOPED_TOKEN_MAX_ORIGINS,
35
+ RNX_CLOUD_SCOPED_TOKEN_MAX_TTL_SECONDS: () => RNX_CLOUD_SCOPED_TOKEN_MAX_TTL_SECONDS,
36
+ RNX_CLOUD_SCOPED_TOKEN_MIN_TTL_SECONDS: () => RNX_CLOUD_SCOPED_TOKEN_MIN_TTL_SECONDS,
37
+ RNX_CLOUD_SCOPED_TOKEN_PREFIX: () => RNX_CLOUD_SCOPED_TOKEN_PREFIX,
33
38
  RNX_CLOUD_TEST_FILES_MAX_BYTES: () => RNX_CLOUD_TEST_FILES_MAX_BYTES,
34
39
  RNX_CLOUD_TEST_FILES_MAX_COUNT: () => RNX_CLOUD_TEST_FILES_MAX_COUNT,
35
40
  RNX_CLOUD_TOKEN_SCOPES: () => RNX_CLOUD_TOKEN_SCOPES,
41
+ isRnxCloudCommandScope: () => isRnxCloudCommandScope,
36
42
  isRnxCloudCommandType: () => isRnxCloudCommandType,
37
43
  isRnxCloudSimStatus: () => isRnxCloudSimStatus,
38
44
  isValidRnxCloudLabel: () => isValidRnxCloudLabel,
@@ -48,6 +54,22 @@ var RNX_CLOUD_DESIGN_MAX_STORAGE_ENTRIES = 256;
48
54
  var RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
49
55
  var RNX_CLOUD_TEST_FILES_MAX_COUNT = 256;
50
56
  var RNX_CLOUD_TEST_FILES_MAX_BYTES = 5e5;
57
+ var RNX_CLOUD_COMMAND_SCOPE_SET = /* @__PURE__ */ new Set([
58
+ "read",
59
+ "drive",
60
+ "reset",
61
+ "media",
62
+ "debug",
63
+ "watch"
64
+ ]);
65
+ function isRnxCloudCommandScope(value) {
66
+ return RNX_CLOUD_COMMAND_SCOPE_SET.has(value);
67
+ }
68
+ var RNX_CLOUD_SCOPED_TOKEN_PREFIX = "sk_rnx_sim_";
69
+ var RNX_CLOUD_SCOPED_TOKEN_DEFAULT_TTL_SECONDS = 3600;
70
+ var RNX_CLOUD_SCOPED_TOKEN_MIN_TTL_SECONDS = 1;
71
+ var RNX_CLOUD_SCOPED_TOKEN_MAX_TTL_SECONDS = 14400;
72
+ var RNX_CLOUD_SCOPED_TOKEN_MAX_ORIGINS = 16;
51
73
  var RNX_CLOUD_COMMAND_SCOPES = {
52
74
  state: "read",
53
75
  tree: "read",
@@ -152,9 +174,15 @@ function isRnxCloudSimStatus(value) {
152
174
  RNX_CLOUD_LABELS_MAX_COUNT,
153
175
  RNX_CLOUD_LABEL_MAX_LENGTH,
154
176
  RNX_CLOUD_MAX_ARTIFACT_BYTES,
177
+ RNX_CLOUD_SCOPED_TOKEN_DEFAULT_TTL_SECONDS,
178
+ RNX_CLOUD_SCOPED_TOKEN_MAX_ORIGINS,
179
+ RNX_CLOUD_SCOPED_TOKEN_MAX_TTL_SECONDS,
180
+ RNX_CLOUD_SCOPED_TOKEN_MIN_TTL_SECONDS,
181
+ RNX_CLOUD_SCOPED_TOKEN_PREFIX,
155
182
  RNX_CLOUD_TEST_FILES_MAX_BYTES,
156
183
  RNX_CLOUD_TEST_FILES_MAX_COUNT,
157
184
  RNX_CLOUD_TOKEN_SCOPES,
185
+ isRnxCloudCommandScope,
158
186
  isRnxCloudCommandType,
159
187
  isRnxCloudSimStatus,
160
188
  isValidRnxCloudLabel,
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/cloud-contract.ts
4
4
  var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
@@ -6,6 +6,22 @@ var RNX_CLOUD_DESIGN_MAX_STORAGE_ENTRIES = 256;
6
6
  var RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
7
7
  var RNX_CLOUD_TEST_FILES_MAX_COUNT = 256;
8
8
  var RNX_CLOUD_TEST_FILES_MAX_BYTES = 5e5;
9
+ var RNX_CLOUD_COMMAND_SCOPE_SET = /* @__PURE__ */ new Set([
10
+ "read",
11
+ "drive",
12
+ "reset",
13
+ "media",
14
+ "debug",
15
+ "watch"
16
+ ]);
17
+ function isRnxCloudCommandScope(value) {
18
+ return RNX_CLOUD_COMMAND_SCOPE_SET.has(value);
19
+ }
20
+ var RNX_CLOUD_SCOPED_TOKEN_PREFIX = "sk_rnx_sim_";
21
+ var RNX_CLOUD_SCOPED_TOKEN_DEFAULT_TTL_SECONDS = 3600;
22
+ var RNX_CLOUD_SCOPED_TOKEN_MIN_TTL_SECONDS = 1;
23
+ var RNX_CLOUD_SCOPED_TOKEN_MAX_TTL_SECONDS = 14400;
24
+ var RNX_CLOUD_SCOPED_TOKEN_MAX_ORIGINS = 16;
9
25
  var RNX_CLOUD_COMMAND_SCOPES = {
10
26
  state: "read",
11
27
  tree: "read",
@@ -109,9 +125,15 @@ export {
109
125
  RNX_CLOUD_LABELS_MAX_COUNT,
110
126
  RNX_CLOUD_LABEL_MAX_LENGTH,
111
127
  RNX_CLOUD_MAX_ARTIFACT_BYTES,
128
+ RNX_CLOUD_SCOPED_TOKEN_DEFAULT_TTL_SECONDS,
129
+ RNX_CLOUD_SCOPED_TOKEN_MAX_ORIGINS,
130
+ RNX_CLOUD_SCOPED_TOKEN_MAX_TTL_SECONDS,
131
+ RNX_CLOUD_SCOPED_TOKEN_MIN_TTL_SECONDS,
132
+ RNX_CLOUD_SCOPED_TOKEN_PREFIX,
112
133
  RNX_CLOUD_TEST_FILES_MAX_BYTES,
113
134
  RNX_CLOUD_TEST_FILES_MAX_COUNT,
114
135
  RNX_CLOUD_TOKEN_SCOPES,
136
+ isRnxCloudCommandScope,
115
137
  isRnxCloudCommandType,
116
138
  isRnxCloudSimStatus,
117
139
  isValidRnxCloudLabel,
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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;
@@ -24,8 +24,11 @@ var cloud_exports = {};
24
24
  __export(cloud_exports, {
25
25
  RNX_CLOUD_COMMAND_TYPES: () => RNX_CLOUD_COMMAND_TYPES,
26
26
  RNX_CLOUD_MAX_ARTIFACT_BYTES: () => RNX_CLOUD_MAX_ARTIFACT_BYTES,
27
+ RNX_CLOUD_SCOPED_TOKEN_PREFIX: () => RNX_CLOUD_SCOPED_TOKEN_PREFIX,
27
28
  RemoteSimulator: () => RemoteSimulator,
29
+ connect: () => connect,
28
30
  createRemoteSimulator: () => createRemoteSimulator,
31
+ isRnxCloudCommandScope: () => isRnxCloudCommandScope,
29
32
  isRnxCloudCommandType: () => isRnxCloudCommandType
30
33
  });
31
34
  module.exports = __toCommonJS(cloud_exports);
@@ -99,6 +102,18 @@ function isRnxScreenCapture(value) {
99
102
  // src/cloud-contract.ts
100
103
  var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
101
104
  var RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
105
+ var RNX_CLOUD_COMMAND_SCOPE_SET = /* @__PURE__ */ new Set([
106
+ "read",
107
+ "drive",
108
+ "reset",
109
+ "media",
110
+ "debug",
111
+ "watch"
112
+ ]);
113
+ function isRnxCloudCommandScope(value) {
114
+ return RNX_CLOUD_COMMAND_SCOPE_SET.has(value);
115
+ }
116
+ var RNX_CLOUD_SCOPED_TOKEN_PREFIX = "sk_rnx_sim_";
102
117
  var RNX_CLOUD_COMMAND_SCOPES = {
103
118
  state: "read",
104
119
  tree: "read",
@@ -336,7 +351,7 @@ function readBoxCreate(value, expectedBytes, expectedSha256) {
336
351
  simulatorToken: simulator.token
337
352
  };
338
353
  }
339
- function cloudCommand(command) {
354
+ function cloudCommand(command, scopes) {
340
355
  const clean = {};
341
356
  for (const [key, value] of Object.entries(command)) {
342
357
  if (key !== "id" && key !== "simId") clean[key] = value;
@@ -344,7 +359,7 @@ function cloudCommand(command) {
344
359
  if (!isRnxCloudCommandType(command.type)) {
345
360
  throw new Error(`RNX Cloud does not support bridge command type ${command.type}`);
346
361
  }
347
- if (!rnxCloudScopesAllowCommand(RNX_CLOUD_TOKEN_SCOPES, command.type)) {
362
+ if (!rnxCloudScopesAllowCommand(scopes, command.type)) {
348
363
  throw new Error(
349
364
  `RNX Cloud command ${command.type} requires the ${rnxCloudCommandScope(command.type)} scope`
350
365
  );
@@ -391,7 +406,10 @@ var RemoteSimulator = class {
391
406
  }
392
407
  return result;
393
408
  },
394
- reset: () => this.sendCommand({ type: "reset" })
409
+ reset: () => this.sendCommand({ type: "reset" }),
410
+ state: (options) => this.sendCommand(
411
+ options === void 0 ? { type: "state" } : { type: "state", stateOptions: options }
412
+ )
395
413
  };
396
414
  }
397
415
  get simId() {
@@ -400,7 +418,13 @@ var RemoteSimulator = class {
400
418
  get claim() {
401
419
  return this.session.claim;
402
420
  }
421
+ get scopes() {
422
+ return this.session.scopes;
423
+ }
403
424
  get receipt() {
425
+ if (!this.session.claim) {
426
+ throw new Error("this simulator was attached with connect() and holds no claim");
427
+ }
404
428
  return {
405
429
  simId: this.session.simId,
406
430
  artifact: this.session.artifact,
@@ -410,8 +434,10 @@ var RemoteSimulator = class {
410
434
  async sendCommand(command, options) {
411
435
  const body = {
412
436
  id: globalThis.crypto.randomUUID(),
413
- claimId: this.session.claim.id,
414
- command: cloudCommand(command)
437
+ // a scoped token drives without a claim: the service checks the token
438
+ // instead. a full token still joins the claim it names here.
439
+ claimId: this.session.claim?.id ?? "",
440
+ command: cloudCommand(command, this.session.scopes)
415
441
  };
416
442
  let response;
417
443
  try {
@@ -450,6 +476,10 @@ var RemoteSimulator = class {
450
476
  return parsed.result;
451
477
  }
452
478
  async confirm() {
479
+ if (!this.session.claim) {
480
+ throw new Error("this simulator was attached with connect() and holds no claim");
481
+ }
482
+ const claimId = this.session.claim.id;
453
483
  const response = await fetchWithCloudRetry(
454
484
  `${this.session.origin}/v1/sims/${encodeURIComponent(this.session.simId)}/claim`,
455
485
  {
@@ -458,7 +488,7 @@ var RemoteSimulator = class {
458
488
  authorization: `Bearer ${this.session.simulatorToken}`,
459
489
  "content-type": "application/json"
460
490
  },
461
- body: JSON.stringify({ claimId: this.session.claim.id })
491
+ body: JSON.stringify({ claimId })
462
492
  }
463
493
  );
464
494
  const text = await response.text();
@@ -470,20 +500,24 @@ var RemoteSimulator = class {
470
500
  throw new Error("RNX Cloud claim returned unreadable JSON");
471
501
  }
472
502
  const claim = readClaim(isRecord(parsed) ? parsed.claim : null);
473
- if (claim.id !== this.session.claim.id) {
503
+ if (claim.id !== claimId) {
474
504
  throw new Error("RNX Cloud confirmation replaced the initial claim");
475
505
  }
476
506
  this.session = { ...this.session, claim };
477
507
  return claim;
478
508
  }
479
509
  async close() {
480
- const response = await fetchWithCloudRetry(
481
- `${this.session.origin}/v1/boxes/${encodeURIComponent(this.session.boxId)}`,
482
- {
483
- method: "DELETE",
484
- headers: { authorization: `Bearer ${this.session.boxToken}` }
485
- }
486
- );
510
+ const target = this.session.boxId !== null && this.session.boxToken !== null ? {
511
+ url: `${this.session.origin}/v1/boxes/${encodeURIComponent(this.session.boxId)}`,
512
+ authorization: `Bearer ${this.session.boxToken}`
513
+ } : {
514
+ url: `${this.session.origin}/v1/sims/${encodeURIComponent(this.session.simId)}`,
515
+ authorization: `Bearer ${this.session.simulatorToken}`
516
+ };
517
+ const response = await fetchWithCloudRetry(target.url, {
518
+ method: "DELETE",
519
+ headers: { authorization: target.authorization }
520
+ });
487
521
  const text = await response.text();
488
522
  if (!response.ok && response.status !== 404) {
489
523
  throw responseError(response.status, text);
@@ -541,16 +575,80 @@ async function createRemoteSimulator(input) {
541
575
  simId: created.receipt.simulator.simId,
542
576
  simulatorToken: created.simulatorToken,
543
577
  claim: created.receipt.simulator.claim,
544
- artifact: created.receipt.artifact
578
+ artifact: created.receipt.artifact,
579
+ scopes: RNX_CLOUD_TOKEN_SCOPES
545
580
  });
546
581
  await simulator.confirm();
547
582
  return simulator;
548
583
  }
584
+ function readSimArtifact(value) {
585
+ if (!isRecord(value) || typeof value.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(value.sha256) || typeof value.bytes !== "number" || !Number.isInteger(value.bytes) || value.bytes <= 0) {
586
+ throw new Error("RNX Cloud returned an invalid simulator artifact");
587
+ }
588
+ return { id: `sha256:${value.sha256}`, bytes: value.bytes };
589
+ }
590
+ function readConnectClaim(value) {
591
+ if (value === null) return null;
592
+ return readClaim(value);
593
+ }
594
+ function readConnectScopes(value, token) {
595
+ if (!token.startsWith(RNX_CLOUD_SCOPED_TOKEN_PREFIX)) return RNX_CLOUD_TOKEN_SCOPES;
596
+ if (!isRecord(value) || typeof value.id !== "string" || !value.id || !Array.isArray(value.scopes) || value.scopes.length === 0 || !value.scopes.every(
597
+ (scope) => typeof scope === "string" && isRnxCloudCommandScope(scope)
598
+ ) || typeof value.expiresAt !== "number") {
599
+ throw new Error("RNX Cloud returned an invalid scoped token");
600
+ }
601
+ return Object.freeze([...value.scopes]);
602
+ }
603
+ async function connect(input) {
604
+ if (!input.id) throw new Error("RNX Cloud connect needs a simulator id");
605
+ if (!input.token) throw new Error("RNX Cloud connect needs a token");
606
+ const origin = resolveOrigin(input.origin);
607
+ let response;
608
+ try {
609
+ response = await fetchWithCloudRetry(
610
+ `${origin}/v1/sims/${encodeURIComponent(input.id)}`,
611
+ { headers: { authorization: `Bearer ${input.token}` } }
612
+ );
613
+ } catch (error) {
614
+ throw new Error(
615
+ `could not reach RNX Cloud at ${origin}: ${error instanceof Error ? error.message : String(error)}`
616
+ );
617
+ }
618
+ const text = await response.text();
619
+ if (!response.ok) throw responseError(response.status, text);
620
+ let parsed;
621
+ try {
622
+ parsed = JSON.parse(text);
623
+ } catch {
624
+ throw new Error("RNX Cloud connect returned unreadable JSON");
625
+ }
626
+ if (!isRecord(parsed) || !isRecord(parsed.sim)) {
627
+ throw new Error("RNX Cloud connect returned an invalid simulator");
628
+ }
629
+ const sim = parsed.sim;
630
+ if (typeof sim.simId !== "string" || !sim.simId) {
631
+ throw new Error("RNX Cloud connect returned an invalid simulator");
632
+ }
633
+ return new RemoteSimulator({
634
+ origin,
635
+ boxId: null,
636
+ boxToken: null,
637
+ simId: sim.simId,
638
+ simulatorToken: input.token,
639
+ claim: readConnectClaim(sim.claim ?? null),
640
+ artifact: readSimArtifact(sim.artifact),
641
+ scopes: readConnectScopes(isRecord(parsed) ? parsed.token : null, input.token)
642
+ });
643
+ }
549
644
  // Annotate the CommonJS export names for ESM import in node:
550
645
  0 && (module.exports = {
551
646
  RNX_CLOUD_COMMAND_TYPES,
552
647
  RNX_CLOUD_MAX_ARTIFACT_BYTES,
648
+ RNX_CLOUD_SCOPED_TOKEN_PREFIX,
553
649
  RemoteSimulator,
650
+ connect,
554
651
  createRemoteSimulator,
652
+ isRnxCloudCommandScope,
555
653
  isRnxCloudCommandType
556
654
  });
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.517 | (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,6 +72,18 @@ 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_SCOPE_SET = /* @__PURE__ */ new Set([
76
+ "read",
77
+ "drive",
78
+ "reset",
79
+ "media",
80
+ "debug",
81
+ "watch"
82
+ ]);
83
+ function isRnxCloudCommandScope(value) {
84
+ return RNX_CLOUD_COMMAND_SCOPE_SET.has(value);
85
+ }
86
+ var RNX_CLOUD_SCOPED_TOKEN_PREFIX = "sk_rnx_sim_";
75
87
  var RNX_CLOUD_COMMAND_SCOPES = {
76
88
  state: "read",
77
89
  tree: "read",
@@ -309,7 +321,7 @@ function readBoxCreate(value, expectedBytes, expectedSha256) {
309
321
  simulatorToken: simulator.token
310
322
  };
311
323
  }
312
- function cloudCommand(command) {
324
+ function cloudCommand(command, scopes) {
313
325
  const clean = {};
314
326
  for (const [key, value] of Object.entries(command)) {
315
327
  if (key !== "id" && key !== "simId") clean[key] = value;
@@ -317,7 +329,7 @@ function cloudCommand(command) {
317
329
  if (!isRnxCloudCommandType(command.type)) {
318
330
  throw new Error(`RNX Cloud does not support bridge command type ${command.type}`);
319
331
  }
320
- if (!rnxCloudScopesAllowCommand(RNX_CLOUD_TOKEN_SCOPES, command.type)) {
332
+ if (!rnxCloudScopesAllowCommand(scopes, command.type)) {
321
333
  throw new Error(
322
334
  `RNX Cloud command ${command.type} requires the ${rnxCloudCommandScope(command.type)} scope`
323
335
  );
@@ -364,7 +376,10 @@ var RemoteSimulator = class {
364
376
  }
365
377
  return result;
366
378
  },
367
- reset: () => this.sendCommand({ type: "reset" })
379
+ reset: () => this.sendCommand({ type: "reset" }),
380
+ state: (options) => this.sendCommand(
381
+ options === void 0 ? { type: "state" } : { type: "state", stateOptions: options }
382
+ )
368
383
  };
369
384
  }
370
385
  get simId() {
@@ -373,7 +388,13 @@ var RemoteSimulator = class {
373
388
  get claim() {
374
389
  return this.session.claim;
375
390
  }
391
+ get scopes() {
392
+ return this.session.scopes;
393
+ }
376
394
  get receipt() {
395
+ if (!this.session.claim) {
396
+ throw new Error("this simulator was attached with connect() and holds no claim");
397
+ }
377
398
  return {
378
399
  simId: this.session.simId,
379
400
  artifact: this.session.artifact,
@@ -383,8 +404,10 @@ var RemoteSimulator = class {
383
404
  async sendCommand(command, options) {
384
405
  const body = {
385
406
  id: globalThis.crypto.randomUUID(),
386
- claimId: this.session.claim.id,
387
- command: cloudCommand(command)
407
+ // a scoped token drives without a claim: the service checks the token
408
+ // instead. a full token still joins the claim it names here.
409
+ claimId: this.session.claim?.id ?? "",
410
+ command: cloudCommand(command, this.session.scopes)
388
411
  };
389
412
  let response;
390
413
  try {
@@ -423,6 +446,10 @@ var RemoteSimulator = class {
423
446
  return parsed.result;
424
447
  }
425
448
  async confirm() {
449
+ if (!this.session.claim) {
450
+ throw new Error("this simulator was attached with connect() and holds no claim");
451
+ }
452
+ const claimId = this.session.claim.id;
426
453
  const response = await fetchWithCloudRetry(
427
454
  `${this.session.origin}/v1/sims/${encodeURIComponent(this.session.simId)}/claim`,
428
455
  {
@@ -431,7 +458,7 @@ var RemoteSimulator = class {
431
458
  authorization: `Bearer ${this.session.simulatorToken}`,
432
459
  "content-type": "application/json"
433
460
  },
434
- body: JSON.stringify({ claimId: this.session.claim.id })
461
+ body: JSON.stringify({ claimId })
435
462
  }
436
463
  );
437
464
  const text = await response.text();
@@ -443,20 +470,24 @@ var RemoteSimulator = class {
443
470
  throw new Error("RNX Cloud claim returned unreadable JSON");
444
471
  }
445
472
  const claim = readClaim(isRecord(parsed) ? parsed.claim : null);
446
- if (claim.id !== this.session.claim.id) {
473
+ if (claim.id !== claimId) {
447
474
  throw new Error("RNX Cloud confirmation replaced the initial claim");
448
475
  }
449
476
  this.session = { ...this.session, claim };
450
477
  return claim;
451
478
  }
452
479
  async close() {
453
- const response = await fetchWithCloudRetry(
454
- `${this.session.origin}/v1/boxes/${encodeURIComponent(this.session.boxId)}`,
455
- {
456
- method: "DELETE",
457
- headers: { authorization: `Bearer ${this.session.boxToken}` }
458
- }
459
- );
480
+ const target = this.session.boxId !== null && this.session.boxToken !== null ? {
481
+ url: `${this.session.origin}/v1/boxes/${encodeURIComponent(this.session.boxId)}`,
482
+ authorization: `Bearer ${this.session.boxToken}`
483
+ } : {
484
+ url: `${this.session.origin}/v1/sims/${encodeURIComponent(this.session.simId)}`,
485
+ authorization: `Bearer ${this.session.simulatorToken}`
486
+ };
487
+ const response = await fetchWithCloudRetry(target.url, {
488
+ method: "DELETE",
489
+ headers: { authorization: target.authorization }
490
+ });
460
491
  const text = await response.text();
461
492
  if (!response.ok && response.status !== 404) {
462
493
  throw responseError(response.status, text);
@@ -514,15 +545,79 @@ async function createRemoteSimulator(input) {
514
545
  simId: created.receipt.simulator.simId,
515
546
  simulatorToken: created.simulatorToken,
516
547
  claim: created.receipt.simulator.claim,
517
- artifact: created.receipt.artifact
548
+ artifact: created.receipt.artifact,
549
+ scopes: RNX_CLOUD_TOKEN_SCOPES
518
550
  });
519
551
  await simulator.confirm();
520
552
  return simulator;
521
553
  }
554
+ function readSimArtifact(value) {
555
+ if (!isRecord(value) || typeof value.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(value.sha256) || typeof value.bytes !== "number" || !Number.isInteger(value.bytes) || value.bytes <= 0) {
556
+ throw new Error("RNX Cloud returned an invalid simulator artifact");
557
+ }
558
+ return { id: `sha256:${value.sha256}`, bytes: value.bytes };
559
+ }
560
+ function readConnectClaim(value) {
561
+ if (value === null) return null;
562
+ return readClaim(value);
563
+ }
564
+ function readConnectScopes(value, token) {
565
+ if (!token.startsWith(RNX_CLOUD_SCOPED_TOKEN_PREFIX)) return RNX_CLOUD_TOKEN_SCOPES;
566
+ if (!isRecord(value) || typeof value.id !== "string" || !value.id || !Array.isArray(value.scopes) || value.scopes.length === 0 || !value.scopes.every(
567
+ (scope) => typeof scope === "string" && isRnxCloudCommandScope(scope)
568
+ ) || typeof value.expiresAt !== "number") {
569
+ throw new Error("RNX Cloud returned an invalid scoped token");
570
+ }
571
+ return Object.freeze([...value.scopes]);
572
+ }
573
+ async function connect(input) {
574
+ if (!input.id) throw new Error("RNX Cloud connect needs a simulator id");
575
+ if (!input.token) throw new Error("RNX Cloud connect needs a token");
576
+ const origin = resolveOrigin(input.origin);
577
+ let response;
578
+ try {
579
+ response = await fetchWithCloudRetry(
580
+ `${origin}/v1/sims/${encodeURIComponent(input.id)}`,
581
+ { headers: { authorization: `Bearer ${input.token}` } }
582
+ );
583
+ } catch (error) {
584
+ throw new Error(
585
+ `could not reach RNX Cloud at ${origin}: ${error instanceof Error ? error.message : String(error)}`
586
+ );
587
+ }
588
+ const text = await response.text();
589
+ if (!response.ok) throw responseError(response.status, text);
590
+ let parsed;
591
+ try {
592
+ parsed = JSON.parse(text);
593
+ } catch {
594
+ throw new Error("RNX Cloud connect returned unreadable JSON");
595
+ }
596
+ if (!isRecord(parsed) || !isRecord(parsed.sim)) {
597
+ throw new Error("RNX Cloud connect returned an invalid simulator");
598
+ }
599
+ const sim = parsed.sim;
600
+ if (typeof sim.simId !== "string" || !sim.simId) {
601
+ throw new Error("RNX Cloud connect returned an invalid simulator");
602
+ }
603
+ return new RemoteSimulator({
604
+ origin,
605
+ boxId: null,
606
+ boxToken: null,
607
+ simId: sim.simId,
608
+ simulatorToken: input.token,
609
+ claim: readConnectClaim(sim.claim ?? null),
610
+ artifact: readSimArtifact(sim.artifact),
611
+ scopes: readConnectScopes(isRecord(parsed) ? parsed.token : null, input.token)
612
+ });
613
+ }
522
614
  export {
523
615
  RNX_CLOUD_COMMAND_TYPES,
524
616
  RNX_CLOUD_MAX_ARTIFACT_BYTES,
617
+ RNX_CLOUD_SCOPED_TOKEN_PREFIX,
525
618
  RemoteSimulator,
619
+ connect,
526
620
  createRemoteSimulator,
621
+ isRnxCloudCommandScope,
527
622
  isRnxCloudCommandType
528
623
  };