rnxsim 0.1.515 → 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 (56) hide show
  1. package/cli/outbound-endpoints.ts +1 -1
  2. package/dist-lib/agent-daemon-client.cjs +1 -1
  3. package/dist-lib/agent-events.cjs +1 -1
  4. package/dist-lib/agent-identity.cjs +1 -1
  5. package/dist-lib/agent-sessions.cjs +1 -1
  6. package/dist-lib/attached-projects.cjs +1 -1
  7. package/dist-lib/auth/shared-session.cjs +1 -1
  8. package/dist-lib/backend-origin.cjs +1 -1
  9. package/dist-lib/beta.cjs +1 -1
  10. package/dist-lib/beta.mjs +1 -1
  11. package/dist-lib/bridge-constants.cjs +1 -1
  12. package/dist-lib/bridge-contract-input.cjs +1 -1
  13. package/dist-lib/bridge-contract-input.mjs +1 -1
  14. package/dist-lib/bridge-contract.cjs +1 -1
  15. package/dist-lib/bridge-contract.mjs +1 -1
  16. package/dist-lib/capture-contract.cjs +1 -1
  17. package/dist-lib/capture-contract.mjs +1 -1
  18. package/dist-lib/cli-constants.cjs +1 -1
  19. package/dist-lib/cloud-contract.cjs +29 -1
  20. package/dist-lib/cloud-contract.mjs +23 -1
  21. package/dist-lib/cloud.cjs +114 -16
  22. package/dist-lib/cloud.mjs +111 -16
  23. package/dist-lib/config.cjs +1 -1
  24. package/dist-lib/detox/index.cjs +1 -1
  25. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  26. package/dist-lib/home-paths.cjs +1 -1
  27. package/dist-lib/host/bridge-host.cjs +1 -1
  28. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  29. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  30. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  31. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  32. package/dist-lib/host/websocket-proxy.cjs +1 -1
  33. package/dist-lib/index.cjs +1 -1
  34. package/dist-lib/jump-to-source-babel.cjs +1 -1
  35. package/dist-lib/jump-to-source-native.cjs +1 -1
  36. package/dist-lib/menu.cjs +1 -1
  37. package/dist-lib/menu.mjs +1 -1
  38. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  39. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  40. package/dist-lib/metro-production-bundle.cjs +1 -1
  41. package/dist-lib/metro-production-bundle.mjs +1 -1
  42. package/dist-lib/metro.cjs +1 -1
  43. package/dist-lib/profiles.cjs +1 -1
  44. package/dist-lib/public-brand.cjs +1 -1
  45. package/dist-lib/react-native-host-modules.cjs +1 -1
  46. package/dist-lib/react-native-host-modules.mjs +1 -1
  47. package/dist-lib/render-mode.cjs +1 -1
  48. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  49. package/dist-lib/sdk.cjs +1 -1
  50. package/dist-lib/sdk.mjs +1 -1
  51. package/dist-lib/skills.cjs +1 -1
  52. package/dist-lib/swift.cjs +1 -1
  53. package/dist-lib/vite.cjs +1 -1
  54. package/package.json +1 -1
  55. package/src/cloud-contract.ts +37 -1
  56. package/src/cloud.ts +178 -21
@@ -374,7 +374,7 @@ export const DECLARED_OUTBOUND_CALLS: Record<string, OutboundCallDeclaration> =
374
374
  'packages/sootsim-engine/src/headless/browser-tenant-worker.ts :: fetch :: new URL(name, assetBase).href':
375
375
  { category: 'same_origin_runtime', count: 1 },
376
376
  // hashes its own delivered script to identify the engine to display clients.
377
- 'packages/sootsim-engine/src/headless/browser-tenant-worker.ts :: fetch :: self.location.href':
377
+ 'packages/sootsim-engine/src/headless/browser-tenant-worker.ts :: fetch :: workerSourceUrl':
378
378
  { category: 'same_origin_runtime', count: 1 },
379
379
  // the tenant build's built-in app chunk prefetch list and the chunk bodies
380
380
  // it names, resolved against the worker chunk's own url.
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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.515 | (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
  });