rnxsim 0.1.516 → 0.1.518

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/detox/index.ts +56 -31
  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 +30 -14
  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
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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
  };
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.518 | (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;
@@ -3267,18 +3267,36 @@ var device = {
3267
3267
  }
3268
3268
  const frameMs = 1e3 / 60;
3269
3269
  const controller = await lockstep.begin(60);
3270
+ const moves = input.hold?.moves ?? [];
3270
3271
  const holdState = {
3272
+ nextMove: 0,
3273
+ pressFrameIndex: null,
3271
3274
  released: false,
3272
- releaseFrameIndex: null
3275
+ x: input.hold?.x ?? 0,
3276
+ y: input.hold?.y ?? 0
3273
3277
  };
3274
- const releaseHoldIfDue = async (receipt) => {
3278
+ const holdEventFrameIndex = (afterMs) => (holdState.pressFrameIndex ?? 0) + Math.ceil(afterMs / frameMs);
3279
+ const nextHoldEventFrameIndex = () => {
3280
+ if (!input.hold || holdState.released || holdState.pressFrameIndex === null) {
3281
+ return null;
3282
+ }
3283
+ const move = moves[holdState.nextMove];
3284
+ return holdEventFrameIndex(move ? move.afterMs : input.hold.durationMs);
3285
+ };
3286
+ const advanceHold = async (receipt) => {
3275
3287
  if (!input.hold || !interact || holdState.released) return;
3276
- if (holdState.releaseFrameIndex === null) {
3277
- holdState.releaseFrameIndex = receipt.frameIndex - 1 + Math.ceil(input.hold.durationMs / frameMs);
3288
+ if (holdState.pressFrameIndex === null) {
3289
+ holdState.pressFrameIndex = receipt.frameIndex - 1;
3278
3290
  }
3279
- if (receipt.frameIndex < holdState.releaseFrameIndex) return;
3291
+ for (let move = moves[holdState.nextMove]; move && receipt.frameIndex >= holdEventFrameIndex(move.afterMs); move = moves[holdState.nextMove]) {
3292
+ holdState.nextMove++;
3293
+ holdState.x = move.x;
3294
+ holdState.y = move.y;
3295
+ await interact.touchMove(move.x, move.y);
3296
+ }
3297
+ if (receipt.frameIndex < holdEventFrameIndex(input.hold.durationMs)) return;
3280
3298
  holdState.released = true;
3281
- await interact.touchUp(input.hold.x, input.hold.y);
3299
+ await interact.touchUp(holdState.x, holdState.y);
3282
3300
  };
3283
3301
  try {
3284
3302
  const baselineBitmap = await captureBitmap();
@@ -3302,7 +3320,7 @@ var device = {
3302
3320
  for (let frame = 0; frame < detectionFrameLimit; frame++) {
3303
3321
  if (state.cancelled) throw new Error("rnx motion capture was cancelled");
3304
3322
  const receipt = await controller.stepFrame();
3305
- await releaseHoldIfDue(receipt);
3323
+ await advanceHold(receipt);
3306
3324
  const candidateBitmap = await captureBitmap();
3307
3325
  const bounds = boundsFor(candidateBitmap);
3308
3326
  const measurement = measureChange({
@@ -3328,14 +3346,12 @@ var device = {
3328
3346
  const snapshots = [];
3329
3347
  for (const stage of input.stages) {
3330
3348
  if (state.cancelled) throw new Error("rnx motion capture was cancelled");
3331
- if (input.hold && !holdState.released && holdState.releaseFrameIndex !== null) {
3332
- const stageFrameIndex = visibleStart.frameIndex + Math.ceil(stage.offsetMs / frameMs);
3333
- while (!holdState.released && stageFrameIndex > holdState.releaseFrameIndex) {
3334
- await releaseHoldIfDue(await controller.stepFrame());
3335
- }
3349
+ const stageFrameIndex = visibleStart.frameIndex + Math.ceil(stage.offsetMs / frameMs);
3350
+ for (let eventFrameIndex = nextHoldEventFrameIndex(); eventFrameIndex !== null && stageFrameIndex > eventFrameIndex; eventFrameIndex = nextHoldEventFrameIndex()) {
3351
+ await advanceHold(await controller.stepFrame());
3336
3352
  }
3337
3353
  const receipt = await controller.stepToOffset(visibleStart, stage.offsetMs);
3338
- await releaseHoldIfDue(receipt);
3354
+ await advanceHold(receipt);
3339
3355
  snapshots.push({
3340
3356
  actualMs: receipt.virtualTimestampMs - visibleStart.virtualTimestampMs,
3341
3357
  bitmap: await captureBitmap(),
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.518 | (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.518 | (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.518 | (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.518 | (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.518 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.518 | (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.518 | (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.518 | (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.518 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.518 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.518 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.518 | (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.518 | (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.518 | (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.518 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.518 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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);
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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.518 | (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/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.516 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.518 | (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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rnxsim",
3
- "version": "0.1.516",
3
+ "version": "0.1.518",
4
4
  "description": "Vite and Metro plugins, testing drivers, and SDK exports for rnx.",
5
5
  "author": "Tamagui LLC",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -6,7 +6,43 @@ export const RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024
6
6
  export const RNX_CLOUD_TEST_FILES_MAX_COUNT = 256
7
7
  export const RNX_CLOUD_TEST_FILES_MAX_BYTES = 500_000
8
8
 
9
- export type RnxCloudCommandScope = 'read' | 'drive' | 'reset' | 'media' | 'debug'
9
+ export type RnxCloudCommandScope = 'read' | 'drive' | 'reset' | 'media' | 'debug' | 'watch'
10
+
11
+ const RNX_CLOUD_COMMAND_SCOPE_SET = new Set<string>([
12
+ 'read',
13
+ 'drive',
14
+ 'reset',
15
+ 'media',
16
+ 'debug',
17
+ 'watch',
18
+ ])
19
+
20
+ export function isRnxCloudCommandScope(value: string): value is RnxCloudCommandScope {
21
+ return RNX_CLOUD_COMMAND_SCOPE_SET.has(value)
22
+ }
23
+
24
+ // scoped simulator tokens: one simulator, one verb set, one expiry, one
25
+ // origin list. minted by the full per-simulator token or the account api key,
26
+ // never by another scoped token, and never carrying debug.
27
+ export const RNX_CLOUD_SCOPED_TOKEN_PREFIX = 'sk_rnx_sim_'
28
+ export const RNX_CLOUD_SCOPED_TOKEN_DEFAULT_TTL_SECONDS = 3600
29
+ export const RNX_CLOUD_SCOPED_TOKEN_MIN_TTL_SECONDS = 1
30
+ export const RNX_CLOUD_SCOPED_TOKEN_MAX_TTL_SECONDS = 14400
31
+ export const RNX_CLOUD_SCOPED_TOKEN_MAX_ORIGINS = 16
32
+
33
+ export interface RnxCloudScopedTokenMint {
34
+ scopes: RnxCloudCommandScope[]
35
+ ttlSeconds?: number
36
+ origins?: string[]
37
+ }
38
+
39
+ export interface RnxCloudScopedToken {
40
+ tokenId: string
41
+ token: string
42
+ scopes: RnxCloudCommandScope[]
43
+ expiresAt: number
44
+ origins: string[]
45
+ }
10
46
 
11
47
  // one scope table for both remote planes: every bridge verb names the scope
12
48
  // that may send it, so the nano service and the box relay admit the same